Thread: A simple but strange code of malloc()

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    284

    A simple but strange code of malloc()

    Here is the code:

    Code:
    #include <stdlib.h>
    #include <stdio.h>
    
    int main(int argc, char *argv[]){
     char *buffer;
     int num_byte;
     num_byte = atoi(argv[1])*1024;
     while(1)
      {buffer=malloc(num_byte);
      free(buffer);
     }
    }
    I use
    strace ./code 126
    It reports:

    Code:
    ....
    brk(0) = 0x804965c
    brk(0x8068e74) = 0x8068e74
    brk(0x8069000) = 0x8069000
    (Nothing further)
    Anybody knows why no more brk()? Note that my code adopts an indefinite loop...

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    But it's freeing the memory immediately after allocating, so it's never using more memory than after the first malloc() inside the loop. malloc() + free() will re-use the same memory location each time. Check it out by printing the first and second pointers...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    as we know, malloc() increase the "heap top brk"
    Free() reduce the brk to return the memory to kernel. So we shall observe indefinite times of "brk(...)" in strace reports, shall we?

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by meili100 View Post
    as we know, malloc() increase the "heap top brk"
    Free() reduce the brk to return the memory to kernel. So we shall observe indefinite times of "brk(...)" in strace reports, shall we?
    Not very likely. In all implementations of malloc() & free() that I've ever seen, free just stores the freed memory in some sort of list of freed memory.

    Whilst brk() is CAPABLE of giving the memory back to the OS, it's so much overhead when you realize that most applications do a slightly more complex version of what you've just used to demonstrate this: allocate one or a few blocks of memory, do some work, free the allocations. Repeat many times.

    It is possible that if you do somehting like this (incomplete - won't compile, but hopefully you follow the idea):
    Code:
    const int blocksize = 1024 * 1024;
    void allocate(int n)
    {
       
       if (n != 0)
       {
          void *p =  malloc(blocksize);
          allocate(n-1));
          free(p);
       }
       else printf("Done!\n");
    }
    
    int main()
    {
       for(;;)
       {
          int n;
          printf("Enter number of levels (0 to exit):");
          scanf("%d", &n);
          if (n == 0)
             return 0;
          allocate(n);
       }
       return 0;
    }
    If you feed in a n of a few hundred, then you may see a reducing break on the way back from "Done!".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    Thanks!! I see. malloc() maintains a "free list" for a memory-pool. Each time it may not call brk() to reduce "brk pointer", instead it adds it to the free list to avoid "stupid applications" teasing it.

    Quote Originally Posted by matsp View Post
    Not very likely. In all implementations of malloc() & free() that I've ever seen, free just stores the freed memory in some sort of list of freed memory.

    Whilst brk() is CAPABLE of giving the memory back to the OS, it's so much overhead when you realize that most applications do a slightly more complex version of what you've just used to demonstrate this: allocate one or a few blocks of memory, do some work, free the allocations. Repeat many times.

    It is possible that if you do somehting like this (incomplete - won't compile, but hopefully you follow the idea):
    Code:
    const int blocksize = 1024 * 1024;
    void allocate(int n)
    {
       
       if (n != 0)
       {
          void *p =  malloc(blocksize);
          allocate(n-1));
          free(p);
       }
       else printf("Done!\n");
    }
    
    int main()
    {
       for(;;)
       {
          int n;
          printf("Enter number of levels (0 to exit):");
          scanf("%d", &n);
          if (n == 0)
             return 0;
          allocate(n);
       }
       return 0;
    }
    If you feed in a n of a few hundred, then you may see a reducing break on the way back from "Done!".

    --
    Mats

  6. #6
    Registered User
    Join Date
    Apr 2007
    Posts
    284
    One more thing: when you use 130 (rather than 126) in my program, you will see malloc() uses mmap/munmap rather than brk(). Really interesting. Does it mean when requesting large memory block, malloc() calls mmap instead of brk()

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by meili100 View Post
    One more thing: when you use 130 (rather than 126) in my program, you will see malloc() uses mmap/munmap rather than brk(). Really interesting. Does it mean when requesting large memory block, malloc() calls mmap instead of brk()
    Interesting. It obviously has some optimization to use brk() vs. mmap(). Presumably that's heuristics based on someones experience.

    For Linux, you can have a look at the libc code and see what it does... I had a very quick look, and as per usual for these type of functions, the malloc function itself is just a proxy for some other function that calls several other functions that then call for example mmap() and sbrk(). The calls to sbrk() or similar is hidden inside a macro called "MORECORE()". I could not find the actual source of the "morecore" that calls mmap() in my 5 minutes search. If you have the libc source code, you can probably do a grep for mmap() in it and find where it's called, and correlate that to the "morecore" function.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with simple piece of code
    By Furious5k in forum C++ Programming
    Replies: 10
    Last Post: 12-12-2008, 05:25 PM
  2. Weird error in this simple code! C2248!
    By gross100 in forum C++ Programming
    Replies: 2
    Last Post: 12-10-2005, 01:31 AM
  3. Replies: 14
    Last Post: 11-23-2005, 08:53 AM
  4. Anybody fix this simple code?
    By Killinger in forum C++ Programming
    Replies: 25
    Last Post: 08-09-2004, 01:53 PM
  5. Simple Code, looking for input.
    By Alien_Freak in forum C Programming
    Replies: 3
    Last Post: 03-03-2002, 11:34 AM