Malloc испортил уже malloc'd память в C - PullRequest
1 голос
/ 26 апреля 2010

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

typedef struct nodo{
    int cantUnos;
    char* numBin;
    struct nodo* sig;
}Nodo;

У нас есть следующий фрагмент кода:

void insNodo(Nodo** lista, char* auxBin, int auxCantUnos){
   printf("*******Insertando\n");
int i;
   if (*lista) printf("DecInt*%p->%p\n", *lista, (*lista)->sig);
Nodo* insert = (Nodo*)malloc(sizeof(Nodo*));
   if (*lista) printf("Malloc*%p->%p\n", *lista, (*lista)->sig);
insert->cantUnos = auxCantUnos;
insert->numBin = (char*)malloc(strlen(auxBin)*sizeof(char));
for(i=0 ; i<strlen(auxBin) ; i++)
    insert->numBin[i] = auxBin[i];
insert->numBin[i] = '\0';
insert->sig = NULL;
Nodo* aux;
/* [etc] */

(строки с дополнительным отступом были моим дополнением для целей отладки)

Это дает мне следующее:

*******Insertando
DecInt*00341098->00000000
Malloc*00341098->2832B6EE

(*lista)->sig ранее и преднамеренно установлен как NULL, который проверяет до этого момента и исправляет потенциальное переполнение буфера (он забыл скопировать NULL-терминатор в insert-> numBin).

Я не могу вспомнить ни одной причины, по которой это произошло, и я не имею ни малейшего представления о том, что еще я должен предоставить в качестве дополнительной информации. (Компиляция на последнем стабильном MinGW под полностью исправленной Windows 7, друг использует MinGW под Windows XP. На моей машине, по крайней мере, в только происходит, когда GDB не подключен.)

Есть идеи? Предложения? Возможные методы экзорцизма? (Текущий хак копирует указатель sig на временную переменную и восстанавливает его после malloc. В любом случае он ломается. Оказывается, что 2-й malloc тоже его повреждает. Интересно, что он сбрасывает sig до того же значения, что и первое).

ОБНОВЛЕНИЕ: Спасибо за ответы. Что касается вещи Node*, она исправлена, но без изменений. По крайней мере, предотвращает потенциальные проблемы впоследствии. Копирование строк не является проблемой, так как я уже сам исправил все пропущенные \ 0s. (Обратите внимание на insertBin[i] = '\0' после for)

Ответы [ 3 ]

1 голос
/ 26 апреля 2010

в этой строке:

Nodo* insert = (Nodo*)malloc(sizeof(Nodo*));

Вы выделяете достаточно памяти только для указателя на Нодо, а не для всего Нодо. Вы хотите:

Nodo* insert = (Nodo*)malloc(sizeof(Nodo));

Кроме того, у вас может быть как минимум еще одна ошибка выделения:

insert->numBin = (char*)malloc(strlen(auxBin)*sizeof(char));
for(i=0 ; i<strlen(auxBin) ; i++)
    insert->numBin[i] = auxBin[i];

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

insert->numBin = strdup(auxBin);

РЕДАКТИРОВАТЬ: только что заметил, что вы находитесь в Windows, поэтому strdup () может быть недоступен (это процедура POSIX), поэтому вы можете покрыть дублирование строк таким образом. Обратите внимание на +1 для длины терминатора:

insert->numBin = (char *)malloc( strlen(auxBin)+1 );
strcpy( insert->numBin, auxBin );
1 голос
/ 26 апреля 2010

Одна проблема - эта строка:

Nodo* insert = (Nodo*)malloc(sizeof(Nodo*)); 

должно быть

Nodo* insert = (Nodo*)malloc(sizeof(Nodo)); 

(Эмпирическое правило: у вас должно быть на 1 меньше '*' в размере ())

Вам необходимо выделить место для структуры Node, NOT место для указателя на структуру Node (которая, кстати, в 32-битных системах будет 4 байта)

Существует похожая проблема с нехваткой места для строки (массив символов); не забудьте пробел для завершающего нуля '\ 0'

0 голосов
/ 26 апреля 2010

Когда вы выделяете память для строки (char *), убедитесь, что она имеет длину strlen + 1 для \ 0 в конце.

insert->numBin = (char*)malloc(strlen(auxBin)*sizeof(char));

должно быть

insert->numBin = (char*)malloc(strlen(auxBin) + 1);

Также нет необходимости говорить * sizeof (char), который равен 1.

Еще одна вещь, которую Джон прав в том, как вы выделяете структуру, это должен быть не размер указателя, а размер структуры.

...