gdb выдает ошибку, но программа работает нормально
-
19-09-2019 - |
Вопрос
У меня есть простая программа на языке Си, которая имеет указатель на массив символов.Чтобы инициировать это, я использую malloc
, и измените размер, а затем установите его x количество раз позже в программе.
Когда я изменяю его размер один раз с помощью realloc
, gdb однако не показывает никаких ошибок, если я попытаюсь снова вызвать функцию изменения размера, gdb показывает следующую ошибку:
warning: Invalid Address specified to RtlReAllocateHeap( 003E0000, 00404076 )
Есть какие-нибудь идеи, почему изменение размера более одного раза приводит к этой ошибке?
Редактировать
Я поиграл с этим, и, похоже, ошибка не возникает, когда я комментирую настройку данных указателя, которая выполняется после изменения размера.
void setName(struct class_x *class, char *name)
{
class->name = (char *) reallocateMemory(class->name, sizeof(char) * strlen(name) + 1);
class->name = name;
}
void *reallocateMemory(void *member, size_t size)
{
void *tmp = realloc(member, size);
if(tmp == NULL)
{
//handle
}
return tmp;
}
Решение
class->name = name
делает не то, что ты думаешь.Использование strncpy()
чтобы скопировать входную строку в вашу недавно выделенную память.Это назначение, которое у вас есть, приводит к утечке выделенной памяти и перезаписи указателя.Тогда в следующий раз, когда ты позвонишь setName()
, в конечном итоге ты звонишь realloc()
с указателем, который вы не получили от malloc()
.Я ожидаю, что ты позвонишь куда-нибудь setName()
с константой, глобальной переменной или строкой локальной переменной, и это то, что в конечном итоге генерирует ошибку.Если бы ты только когда-нибудь звонил setName()
со строками, память о которых вы получили от malloc()
, вы бы не увидели предупреждение от gdb (но у вас все равно была бы ошибка!).
Другие советы
запустите его под valgrind или electric fence - они обнаружат перерасход памяти для вас