Как освободить перераспределенную память? C ++ - PullRequest
8 голосов
/ 27 марта 2012

Я пытаюсь освободить перераспределенную память, но получаю ошибку ...

float * foo = NULL;
float * bar = NULL;

void update()
{
    ...
    foo = (float *)malloc( a * 2 * sizeof(float));
    ...
    bar = (float *)realloc( foo, a * 2 * sizeof(float));
    ...
    free( foo );
    ...
    // when i do
    if(bar != NULL)
    {
        free(bar); // <-- error at executing
    }
}

Я получаю ошибку: http://d.pr/mpBF, и Visual Studio показывает мне следующий файл:

osfinfo.c
=========
void __cdecl _unlock_fhandle (
        int fh
        )
{
        LeaveCriticalSection( &(_pioinfo(fh)->lock) );
}

Есть идеи?

Ответы [ 4 ]

6 голосов
/ 27 марта 2012
foo = (float *)malloc( a * 2 * sizeof(float));
bar = (float *)realloc( foo, a * 2 * sizeof(float));
free( foo ); // oops, foo has gone

В момент, когда вы звоните free(foo), foo недопустим, поскольку он был уже освобожден, когда вы вызывали realloc.

Код должен быть примерно таким: псевдокод:

foo = (float *)malloc( a * 2 * sizeof(float));
if (foo == NULL) 
    return ERROR_CODE;
...
bar = (float *)realloc( foo, a * 2 * sizeof(float));
if (bar == NULL) 
{
    free(foo);
    return ERROR_CODE;
}
...
free(bar);
return SUCCESS;

Конечно, поскольку это C ++, вам следует избегать malloc и free в целом и использовать std::vector<float>.

2 голосов
/ 27 марта 2012

Когда вы перераспределяете память, вы не должны освобождать старую память.

bar = (float *)realloc( foo, a * 2 * sizeof(float));
free( foo ); // <-- this is wrong

Вы хотите:

float * foo = NULL;

void update()
{
    ...
    foo = (float *)malloc( a * 2 * sizeof(float));
    ...
    float * bar = (float *)realloc( foo, a * 2 * sizeof(float));
    if(bar)
       foo = bar;
    ...
    free(foo);
}
2 голосов
/ 27 марта 2012

Я предполагаю, что вызов realloc обрабатывает , расширяет память, выделенную вызовом для malloc. В этом случае foo и bar будут указывать на один и тот же адрес памяти, и вы будете free ing foo где-то перед попыткой free bar, что приведет к двойному удалению.

Вам вообще не нужно free( foo ), потому что realloc сделает это за вас, если область памяти была перемещена во время перераспределения. Со связанной страницы:

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

1 голос
/ 27 марта 2012

Как только вы передали указатель на realloc(), он формально освобождается (освобождается), и вы не должны его снова освобождать.

C99 §7.20.3.4 Функция realloc

2 Функция realloc освобождает старый объект, на который указывает ptr, и возвращает указатель на новый объект, размер которого определяется размером.Содержимое нового объекта должно быть таким же, как и у старого объекта до освобождения, до меньшего из нового и старого размеров.Любые байты в новом объекте, превышающие размер старого объекта, имеют неопределенные значения.

Может случиться, что realloc() вернет тот же указатель, который был задан, но вы не можете предполагать, что он будет вгенеральный.И как только вы передали указатель на realloc() (или free()), вы должны предположить, что он больше не является допустимым указателем.

Правила в C ++ в основном одинаковы;он включает в себя стандарт C89 для функций из C, таких как realloc().

Ваша система правильно заявляет, что вы освобождаете нераспределенную память.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...