简体   繁体   中英

How to free reallocated memory? C++

I'm trying to free memory that's reallocated but I get an error...

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
    }
}

I get error: http://d.pr/mpBF and visual studio shows me the following file:

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

Any ideas?

foo = (float *)malloc( a * 2 * sizeof(float));
bar = (float *)realloc( foo, a * 2 * sizeof(float));
free( foo ); // oops, foo has gone

At the point at which you call free(foo) , foo is invalid since it was already freed when you called realloc .

The code should be something like this pseudo-code:

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;

Of course, since this is C++, you should be avoiding malloc and free altogether and using std::vector<float> .

My guess is that the realloc call manages to extend the memory allocated by the call to malloc . In this case both foo and bar will point to the same memory address, and you're free ing foo somewhere before trying to free bar resulting in a double deletion.

You do not need to free( foo ) at all because realloc will do that for you if the memory area was moved during reallocation. From the linked page:

If the area pointed to was moved, a free(ptr) is done.

When you realloc memory you should not free the old memory.

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

You want:

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);
}

Once you've passed a pointer to realloc() , it is formally deallocated (freed) and you must not free it again.

C99 §7.20.3.4 The realloc function

2 The realloc function deallocates the old object pointed to by ptr and returns a pointer to a new object that has the size specified by size. The contents of the new object shall be the same as that of the old object prior to deallocation, up to the lesser of the new and old sizes. Any bytes in the new object beyond the size of the old object have indeterminate values.

It may happen that realloc() returns the same pointer as it was given, but you cannot assume that it will in general. And once you've passed a pointer to realloc() (or free() ) you must assume it is no longer a valid pointer.

The rules in C++ are basically the same; it incorporates the C89 standard for functions from C such as realloc() .

Your system is correct to complain that you're freeing unallocated memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM