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?
In C, the library function malloc is used to allocate a block of memory on the heap. The program accesses this block of memory via a pointer that malloc returns. When the memory is no longer needed, the pointer is passed to free which deallocates the memory so that it can be used for other purposes.
However on long running programs, failing to free memory means you will be consuming a finite resource without replenishing it. Eventually it will run out and your program will rudely crash. This is why you must free memory.
When memory blocks are allotted by calloc(), malloc(), or realloc() functions, the C library function free() is used to deallocate or release the memory blocks to reduce their wastage. free() function in C should only be used either for the pointers pointing to the memory allocated using malloc() or for a NULL pointer.
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>
.
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);
}
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With