Вопрос

У меня есть простая программа на языке Си, которая имеет указатель на массив символов.Чтобы инициировать это, я использую 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 - они обнаружат перерасход памяти для вас

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top