How to free memory that has been allocated by sbrk()? Can I use munmap?

1.2k Views Asked by At

I am having a hard time understanding sbrk() and mmap(), as well as munmap().

This is closely related to How do I free memory obtained by sbrk()? but I have more questions.

If I have the following program:

int main(void) {

   void* first = sbrk(4096);
   void* second = sbrk(4096);

   return 0;
}

From what I understand, sbrk() will increase the size of the heap by the value that was passed in, and then return a pointer to the beginning of that memory segment.

So for example if the current heap break (end of heap) is at 0x1000, and I call void* first = sbrk(4096), the heap break will then be at 0x2000 and the pointer returned will be 0x1000.

So I assume then that when I call void* second = sbrk(4096), the heap break will be at 0x3000 and the pointer returned will be 0x2000?

When it comes to freeing this memory, I understand that if you call sbrk() again, I think sbrk(-4096), that will free heap memory. But won't that free void* second, what happens if I want to free void* first?

Also, can I used munmap to unmap that allocated memory from sbrk()? So call something like munmap(second, 4096); or can that only be used if I used mmap() to allocate the memory?

Thanks, Juan

Please note, this is for a university assignment, I would just use malloc and free but the assignment is to reimplement malloc.

1

There are 1 best solutions below

3
KamilCuk On BEST ANSWER

So I assume then that when I call void* second = sbrk(4096), the heap break will be at 0x3000 and the pointer returned will be 0x2000?

Yes.

When it comes to freeing this memory, I understand that if you call sbrk() again, I think sbrk(-4096), that will free heap memory. But won't that free void* second,

It will "free second" - free 4096 bytes.

what happens if I want to free void* first?

You have to call them in order.

 void *first = sbrk(4096);
 void *second = sbrk(4096);
 sbrk(-4096);
 sbrk(-4096);

or just sbrk(-4096 * 2);.

can I used munmap to unmap that allocated memory from sbrk()?

No.

So call something like munmap(second, 4096);

No.

or can that only be used if I used mmap() to allocate the memory?

Yes.


Sbrk moves a pointer and returns an older address. A over-simplistic implementation could be like:

char heap_memory[1000000];
char *heap = heap_memory;
char *heap_end = heap + 1000000;
void *sbrk(int toadd) {
    // check for out of memory
    if (heap + toadd > heap_end) return NULL;
    // increment heap and return the old address
    char *old_address = heap;
    heap += toadd;
    return old_address;
}

Just moves a pointer within some buffer. mmap is a different mechanisms, that maps the memory address you chose to some data. You can't pass value returned by sbrk to mmap.