2014-01-16 2 views
2

Я очень новичок в использовании Linux и создании чего-то отдаленно серьезного на C. Я пытаюсь создать программу, которая просто сжимает одну строку, но я продолжаю получать эту Сегментацию при попытке запустить скомпилированный файл. Я составил его с помощью:Ошибка сегментации (ядро сбрасывается) и zlib

gcc 2.c -o test.o -lz 

Мой код:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <zlib.h> 
#include <assert.h> 
int main() 
{ 
char *istream = malloc(10), *ostream = malloc(120); 
istream = "istream"; 
int res = compress(ostream, (uLongf *)strlen(ostream), istream,(ulong)strlen(istream)); 
return 0; 
} 

Может кто-нибудь объяснить мне, почему эта ошибка происходит и как я могу улучшить мой код?

+0

Зачем стоит тэг 'C++'? –

ответ

2

Эта линия, казалось бы, главная проблема:

(uLongf*)strlen(ostream) 

Вы интерпретируя значение size_t как указатель на буфер. Вы должны передать адрес unsigned long, содержащий длину выходного буфера. Еще раз взгляните на документацию для compress.

Кроме того, вы еще не понимаете, как работают строки C. Оператор присваивания при использовании с char* lvalue просто копирует адрес, а не содержимое строки. Я полагаю, что вы заявляете свои буфера, как это:

const char *istream = "istream"; 
char ostream[120]; 

Я думаю, что ваша программа должна быть что-то вдоль этих линий:

int main(void) 
{ 
    const char *istream = "istream"; 
    char ostream[120]; 
    uLongf destLen = sizeof(ostream); 
    int res = compress((Bytef*)ostream, &destLen, (Bytef*)istream, strlen(istream)); 
    return 0; 
} 

Обратите внимание, что я написал код, предполагая, что вы используете компилятор Си. И, следовательно, int main(void).

+0

Этот параметр будет фактическим размером вывода после сжатия, когда функция вернется, поэтому он является «выходным» параметром. –

+1

@JoachimPileborg Это как вход, так и выход. Я исправил свой ответ. –

1

Изменение:

istream = "istream" 

Для

strcpy(istream,"istream"); 

Кроме того, что вы ожидаете strlen(ostream) вернуться? 120?

strlen возвращает индекс первого символа 0, встречающегося внутри входной строки.

В вашем случае содержимое памяти, на которое указывает ostream, неизвестно (т. Е. «Мусор»).

сканирует эту память до тех пор, пока не встретится символ 0, но, вероятно, превысит 120-байтовое пространство памяти и вызовет нарушение доступа к памяти.

Изменить strlen(ostream) до 120 Если это было вашим намерением.

+0

Пробовал и это, и sprintf (istream, «istream»), все еще дает ошибку сегментации. – FalconD

+0

Также требуется распределение памяти. –

+0

Ну, если исключение segfault возникает, когда вы вызываете 'compress', почему бы вам не опубликовать эту функцию как часть вашего вопроса? –

2

Сначала вы делаете istream точку в памяти вы выделяете:

char *istream = malloc(10) 

затем вы сделаете это указывает на буквальное (и, следовательно, постоянным и только для чтения) строку:

istream = "istream"; 

Вам необходимо указать копию строковый литерал в выделенную память, иначе у вас больше не будет указателя оригинала и имеют утечку памяти. Вы также не сможете указать free, указатель, так как istream указывает на то, что вы не выделили malloc.

Что касается аварии, см. Ответ Дэвида Хеффернана.


В качестве побочного сведению, там нет C++ в вашем коде, только чистая и простая C.

Смежные вопросы