posixsbrk

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


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.


Solution

  • 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.