Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C and C++: Freeing PART of an allocated pointer

Let's say I have a pointer allocated to hold 4096 bytes. How would one deallocate the last 1024 bytes in C? What about in C++? What if, instead, I wanted to deallocate the first 1024 bytes, and keep the rest (in both languages)? What about deallocating from the middle (it seems to me that this would require splitting it into two pointers, before and after the deallocated region).

like image 809
Imagist Avatar asked Aug 20 '09 08:08

Imagist


People also ask

What does freeing a pointer do in C?

The function free takes a pointer as parameter and deallocates the memory region pointed to by that pointer. The memory region passed to free must be previously allocated with calloc , malloc or realloc . If the pointer is NULL , no action is taken.

How will you free the allocated memory in C?

The free() function is used to manually free the memory allocated at run-time. The free() function is defined in the same <stdlib. h> header. The function takes a pointer and frees the memory the pointer is pointing towards.

Can I free () pointers allocated with new?

No! It is perfectly legal, moral, and wholesome to use malloc() and delete in the same program, or to use new and free() in the same program. But it is illegal, immoral, and despicable to call free() with a pointer allocated via new, or to call delete on a pointer allocated via malloc().

What is responsible for freeing the unused memory?

The garbage collector finds these unused objects and deletes them to free up memory.


2 Answers

Don't try and second-guess memory management. It's usually cleverer than you ;-)

The only thing you can achieve is the first scenario to 'deallocate' the last 1K

char * foo = malloc(4096);

foo = realloc(foo, 4096-1024);

However, even in this case, there is NO GUARANTEE that "foo" will be unchanged. Your entire 4K may be freed, and realloc() may move your memory elsewhere, thus invalidating any pointers to it that you may hold.

This is valid for both C and C++ - however, use of malloc() in C++ is a bad code smell, and most folk would expect you to use new() to allocate storage. And memory allocated with new() cannot be realloc()ed - or at least, not in any kind of portable way. STL vectors would be a much better approach in C++

like image 193
Roddy Avatar answered Sep 21 '22 09:09

Roddy


You don't have "a pointer allocated to hold 4096 bytes", you have a pointer to an allocated block of 4096 bytes.

If your block was allocated with malloc(), realloc() will allow you to reduce or increase the size of the block. The start address of the block won't necessarily stay the same, though.

You can't change the start address of a malloc'd memory block, which is really what your second scenario is asking. There's also no way to split a malloc'd block.

This is a limitation of the malloc/calloc/realloc/free API -- and implementations may rely on these limitations (for example, keeping bookkeeping information about the allocation immediately before the start address, which would make moving the start address difficult.)

Now, malloc isn't the only allocator out there -- your platform or libraries might provide other ones, or you could write your own (which gets memory from the system via malloc, mmap, VirtualAlloc or some other mechanism) and then hands it out to your program in whatever fashion you desire.

For C++, if you allocate memory with std::malloc, the information above applies. If you're using new and delete, you're allocating storage for and constructing objects, and so changing the size of an allocated block doesn't make sense -- objects in C++ are a fixed size.

like image 32
Stephen Veiss Avatar answered Sep 20 '22 09:09

Stephen Veiss