Reputation: 31
Why does this not cause a memory leak? I allocate space for a long long on the heap, and then change the pointer I get back to a char*. Afterwards, I call delete (or free, in the second example) on this pointer. Both of these examples do not seem to cause a memory leak.
#include <stdlib.h>
struct leaky {
long long* testptr;
leaky() {testptr = new long long; }
~leaky() { void* newptr = (void*) testptr;
char* newptr2 = (char*) newptr;
delete newptr2; }
};
struct leaky2 {
long long* testptr;
leaky2() { testptr = (long long*) malloc(sizeof(long long)); }
~leaky2() { void* newptr = (void*) testptr;
char* newptr2 = (char*) newptr;
free (newptr2); }
};
int main() {
while (true) {
{
leaky leak = leaky();
}
}
}
I tested this on: gcc version 4.6.3 20120306 (Red Hat 4.6.3-2) (GCC) on a Unix system.
Upvotes: 3
Views: 645
Reputation: 616
When using malloc or new the space used consists of both "overhead" (info relating to the size of used and free blocks of memory, the actual pointer to the space you need) and "payload" (the memory being used).
One form of jargon used for this book keeping info is an "initialisation record" that may resemble the following struct
struct InitRecord
{
int memBlockSize;
void* mem;
};
This is how malloc remembers how much mem you used. A good way to understand further (and a fun exercise!) is to create your own heap allocator.
Good reference material here http://www.cs.ucsb.edu/~rich/class/cs170/labs/lab1.malloc/index.html
and here
http://systematicgaming.wordpress.com/2008/08/05/memory-management-introduction/
Upvotes: 0
Reputation: 86525
Any pointer to memory can be converted to a char*
and back and have the same value. So casting to char*
just changes how the compiler interprets the value (what sizeof(*ptr)
returns, etc). It doesn't change the value of the pointer.
operator delete
and free()
accept a void*
. So by the time either is asked to free the memory, any notion of "type" is gone from it anyway. They have to be able to account for that and work with the memory without knowing anything about what those bytes used to be.
For reference, they often do so by allocating a little extra memory and recording the size of that memory in some bytes right before the address returned to you. But that's an implementation detail; don't rely on it.
Upvotes: 0
Reputation: 208353
The first piece of code is undefined behavior, as you cannot delete
from a type that is unrelated to what you new
-ed. The second case is correct, so we can discuss that one.
The interface to malloc
and free
is based on void*
, so the type does not quite matter here, but the question remains: how does free
know how much was allocated with malloc
? and the answer is that it is implementation defined. It can be done in different ways. The allocator can acquire a larger block of memory and store the information in that extra space. In some cases malloc
allocates from different pools for different fixed sizes (specially for small objects), so the information need not be tracked with a possibly small object. In those cases the implementation of free
only needs to figure out what pool the memory came from and return the block to the pool.
Upvotes: 6
Reputation: 693
malloc
associates some bookkeeping information with the value of the address it returns to you (sometimes in the memory region just before the address). This bookkeeping information contains the size of the allocation. Casting addresses around doesn't change the value of this address, only the interpretation of it by your code.
Upvotes: 4