tags:

views:

244

answers:

9

When malloc is called, the size is stored adjacent to the allocated block so that free will know how much to free etc ( http://c-faq.com/malloc/freesize.html ).

My question is, Say we have dynamically allocated memory and later in the code we increment the pointer

 pointer++

And then later, if i call a

free(pointer) 

what memory does actually get freed up.

Is it number of allocated bytes starting from the current address pointed by 'pointer' or from the base address to which it has been allocated.

+5  A: 

It will cause undefined behavior. Most likely it will crash your program either instantly or later.

Tronic
For further information, read about how the heap works. The most common heap implementation is a bidirectional linked list that contains its bookkeeping information between the blocks of user data (areas returned by malloc). The bookkeeping data consists of pointers or offsets to previous/next area and status information stating whether the area is allocated or not.
Tronic
@Tronic: Or it could lead to silent data corruption, which is worse.
David Thornley
@Tronic: That's the common implementation on unix platforms. Windows uses the RtlHeap library, see ( http://msdn.microsoft.com/en-us/library/ms797604.aspx ), which works completely differently.
Billy ONeal
@Billy: There is nothing in that article that indicates it works differently, and nothing is, in fact, said concretely about how the heap is internally structured except that it uses some space: "The system uses memory from the private heap to store heap support structures ... the request may fail because of system overhead."
Roger Pate
@Roger Pate: I wasn't saying that Tronic was incorrect. Unfortunately the only good resource I could find detailing how RtlHeap works internally is a book on my shelf ("Secure Coding in C and C++") EDIT: And for the record, I upvoted his answer ;)
Billy ONeal
@Billy: How does it work differently?
Roger Pate
@Roger Pate: Hmm.. let's see: 1. It does not maintain a doubly linked list to user allocated blocks. 2. It copes with the possibility of multiple heaps -- most windows applications have at least 2. 3. Most common small size lookups are done with singly linked lists that are not allocated as part of user memory blocks. 4. For allocations greater than 4k, it passes the entire request down the line to the `VirtualAlloc` functions, etc. Doug Lea's `malloc` is the implementation common to Unixen and is the one which relies on doubly linked lists to user data.
Billy ONeal
@Billy: Do you know where to read more about it? The article linked previously said nothing of any differences.
Roger Pate
@Roger Pate: As mentioned a few comments ago, the only place I've found this info is in "Secure Coding in C and C++", where they are discussing double-free vulnerabilities. They go in depth of both allocators to discuss potential problems with double-frees. (http://www.amazon.com/Secure-Coding-Robert-C-Seacord/dp/0321335724)
Billy ONeal
+4  A: 

That's undefined behavior. And it will most probably results in problem later on.

AProgrammer
+2  A: 

This is what we call a memory leak/segmentation fault.

You HAVE to pass the same pointervalue to free() as the one you got from malloc() or your application will misbehave/crash.

haavee
It will crash if you are a lucky, clean-living person. Usually it misbehaves in very obscure, inconsistent ways.
S.Lott
I'd restrict the term "memory leak" to repeatedly using malloc() on a pointer that never gets free()'ed.
Arthur Kalliokoski
Actually it's what we call undefined behavior and corruption, which are subtly different from leaks and segfaults (but the former two can certainly result in the latter two); however, it's practically pointless to worry about memory leaks when you have UB of this magnitude.
Roger Pate
+3  A: 

If you increment the pointer without saving the original malloced location you can't call free on it. You have to save the original location somewhere and use a temporary point when you increment.

Hogan
+1  A: 

doing pointer++ to original pointer is terribly wrong. result of freeing it may be different on different implementations, but you definitely shouldn't do it.

Andrey
What? Pointer arithmetic is wrong? Well we have to throw out 99% of C programs then....
Billy ONeal
"to original pointer" read carefully. i meant without preserving the one returned by malloc
Andrey
+14  A: 

You need to free() the same pointer as you received from malloc(). Incrementing, altering or changing it is undefined behaviour, that is usually a segmentation fault.

Think of the pointer you receive as a book from the library. You go home and read it. Then you remove the front page and the book's back and hand it back .. will the librarian accept it, will he know what the book is about? Or are you in serious trouble then?

Alexander Gessler
by the hard-back :D
n00b32
Thanks, fixed :-)
Alexander Gessler
"Usually"? I applaud your optimism!
Roger Pate
you easily manipulate a copy of the original pointer, just be sure to remember the original value. fine analogy with the library. especially since malloc IS in a library :)
haavee
@havee: IOW, you *can* keep a bookmark in the book, and move it around as needed :-)
Tim Schaeffer
+6  A: 

You can only call free() on a value that you previously obtained from malloc(), calloc(), or realloc() (or NULL). Everything else is undefined.

For example, an implementation might store the size of the allocated block in 4 bytes before the return address from malloc(). Then, free() goes back 4 bytes and finds out the size. This wouldn't work if you don't pass the original pointer back to free().

Alok
A: 

The pointer returned by malloc() points directly to the memory on the heap that will be used by your program.

However, this isn't the only memory that's allocated. A few bytes are allocated in the memory locations immediately preceding the pointer returned that indicate the size of the chunk on the heap. This isn't used by your program, but it will definitely be needed by free.

When free(p) is called, the information about its chunk on the heap is contained in, say, the locations from p-4 through p-1. This depends on implementation of course, but the details need not concern the programmer. The only thing that the programmer needs to know is that free uses that area of memory to free the chunk of memory from the heap, and that area is derived from the original pointer p.

In other words, if you call free on p, it will only make sense if malloc once returned exactly p.

If you pass in a pointer that wasn't created with malloc, who knows what will lie at p-1, p-2, etc.? It will probably result in a catastrophic failure.

scrapdog
No, that "few bytes preceding" refers only to some types of implementations of malloc. It's completely different on Windows machines.
Billy ONeal
afaik this metainfo about size is stored in linked list not in few bytes before in MAIN implementations
Andrey
+2  A: 

The code managing the free storage just assumes that you wouldn't hand it the wrong pointer. It takes whatever you give, doesn't check its plausibility, and interprets it the same way it would interpret the right pointer. It will act according to whatever values it reads from whatever memory locations it looks at assuming the pointer was rightfully obtained. If you handed it a stray pointer, it will find nonsensical values and thus act nonsensical.

This is called undefined behavior and it's a mean thing. It might format your hard drive, toast your CPU, or make your program seemingly work the way it is expected to until you retire. You never know.

sbi