повреждение памяти в malloc, fopen - PullRequest
3 голосов
/ 19 октября 2011

Я пытался использовать GDB и Valgrind, но я не могу точно определить проблему.Интересно, что программа вылетает при нормальном выполнении и GDB, но не Valgrid.

Чтобы помочь вам следовать за кодом, вот основная идея программы: связываться с сервером через сокеты и UDP для передачи файла и обрабатывать некоторые основные потери пакетов.

Я не буду делиться кодом сервера, потому что я знаю, что проблема не в этом.Дело в том, что некоторые могут запутать то, что я сам реализую потерю пакетов с помощью генератора чисел.Сейчас он ничего не делает, кроме того, что заставляет программу использовать другой recvfrom.

Чтобы показать, как работает программа, клиент сообщает серверу, какой файл ему нужен, сервер сообщает клиенту, какой файл он собирается отправить, а затем отправляет его кусками (по 10 символов ввремя).

Выходные данные показывают, какой кусок отправлен, сколько символов получено и какова составная строка.

Передача файлов прошла успешно, что я могу сказать, это просто вызов fopen, который я использую для записи полученного файла, что доставляет мне проблемы.Не уверен, связано ли это с моим вызовом malloc или нет.

Вот исходный код:

pastebin.com / Z79hvw6L

Здесь приведены результаты выполнения CLI и Valgrind (GDB, похоже, не дает больше информации):

Обратите внимание, что CLI выдает ошибку повреждения памяти malloc, а Valgrind - нет.

CLI: http://pastebin.com/qdTKMCD2

VALGRIND: http://pastebin.com/8inRygnU

Спасибо за любую помощь!

Добавлены результаты GDB Backtrace

======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x6b961)[0x19a961]
/lib/i386-linux-gnu/libc.so.6(+0x6e15d)[0x19d15d]
/lib/i386-linux-gnu/libc.so.6(__libc_malloc+0x63)[0x19ef53]
/lib/i386-linux-gnu/libc.so.6(+0x5c2b8)[0x18b2b8]
/lib/i386-linux-gnu/libc.so.6(fopen+0x2c)[0x18b38c]
/home/---/client[0x8048dc2]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x145e37]
/home/---/client[0x8048871]

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

Ответы [ 3 ]

3 голосов
/ 19 октября 2011
char chunk[10];
chunk[10] = '\0';

неверно, чанк [10] - один за массивом.

И вообще, будьте осторожны с этим

char filename[25];
scanf("%s",filename);

Если вы вводите длинное имя файла,ты испортишь памятьлучше использовать fgets ().Вы также, по крайней мере, захотите проверить, успешно ли выполняется scanf, иначе следующая строка strlen () в имени файла недопустима.

строка 93, buf[strlen(buf)-1]='\0'; опасна, вы не можете использовать strlen, если буферне завершено, и вы очищаете память, если buf - пустая строка, так как вы индексируете buf [-1].

Редактировать.Другая ваша проблема - strcat(fullstring,chunk);, у вас нет элемента управления в цикле, который прекращает добавление к этой строке, если вы получаете больше данных, чем они могут удержать.Размер также, вероятно, на единицу, так как вам нужно место для последнего нулевого терминатора.Сделайте это как минимум char * fullstring = malloc(sizeof(char)*filesize + 1 ); Но ваш цикл действительно должен проверить, что он не записывает после конца этого буфера.

Что касается добавления нулевого терминатора в buf, вызов recv возвращает количество байтов.вы прочитали, поэтому, если вы проверили recv на наличие ошибок, выполните buf[numbytes] = 0, но это также будет отключено на единицу, поскольку вы выделили 10 байтов для buf, и вы пытаетесь прочитать в нем 10 байтовтакже - но в C строке также требуется место для нулевого терминатора.Сделайте буфер размером 11 байт.Или recv () только 9 байтов.

На самом деле, у вас слишком много мест, поэтому начните считать, сколько байт вам нужно, и вы положили в них вещи.Помните, что в C массивы начинаются с индекса ноль, а массив из 10 может индексироваться только индексом от 0 до 9.

2 голосов
/ 19 октября 2011

Это (строка 93) подозрительно:

buf[strlen(buf)-1]='\0';

ОБНОВЛЕНИЕ Это (строка 99,100) также неправильно:

char chunk[10];
chunk[10] = '\0';

ОБНОВЛЕНИЕ2: слишком маленький буфер

char * fullstring = malloc(sizeof(char)*filesize); // line 103
...
strcat(fullstring,chunk); // line 124

Update3: UDP ненадежен. Передача пакета может быть неудачной (пакеты могут быть отброшены в любом месте между отправителем и получателем), и пакеты могут быть получены в другом порядке, в котором вы их отправили.

1 голос
/ 19 октября 2011

Что ж, это не должно быть проблемой в современных ОС: если вы не проверяете возвращаемое значение из malloc () для NULL. На какой линии происходит сбой и с каким сигналом?

...