CS360 Lecture notes -- Malloc Lecture #1 -- note about different systems

  • Jim Plank
  • Directory: /home/plank/cs360/notes/Malloc1
  • Lecture notes: http://web.eecs.utk.edu/~jplank/plank/classes/cs360/360/notes/Malloc1/diff.html
    Each system implements malloc() in its own way. The description that I give in class is how Solaris systems implemented malloc() and free() in 1996. I use it because it is easy to explain.

    When you run fb4 on current machines, the output will be different. For example, here is the output on a Cetus lab machine in 1999:

    UNIX> fb4
    sbrk(0) = 0x20b08
    Allocated 4 bytes.  buf = 0x20b18, buf[-1] = 0, buf[-2] = 9, buf[0] = 1000
    Allocated 8 bytes.  buf = 0x20b28, buf[-1] = 0, buf[-2] = 9, buf[0] = 1001
    Allocated 12 bytes.  buf = 0x20f20, buf[-1] = 0, buf[-2] = 17, buf[0] = 1002
    Allocated 16 bytes.  buf = 0x20f38, buf[-1] = 0, buf[-2] = 17, buf[0] = 1003
    Allocated 20 bytes.  buf = 0x21528, buf[-1] = 0, buf[-2] = 25, buf[0] = 1004
    Allocated 24 bytes.  buf = 0x21548, buf[-1] = 0, buf[-2] = 25, buf[0] = 1005
    Allocated 28 bytes.  buf = 0x21d30, buf[-1] = 0, buf[-2] = 33, buf[0] = 1006
    Allocated 100 bytes.  buf = 0x22730, buf[-1] = 0, buf[-2] = 105, buf[0] = 1007
    sbrk(0) = 0x22b08
    UNIX> 
    
    This is different from the 1996 output, but as you can see, it is functionally equivalent -- the value in the word two words before the returned pointer is seven less than the number of bytes allocated. Why? I don't know -- but all you have to do is add seven to it to get the chunk size.

    The Pentium box on my desk in 2002 had the following output:

    UNIX> fb4
    sbrk(0) = 0x8049778
    Allocated 4 bytes.  buf = 0x8049780, buf[-1] = 17, buf[-2] = 0, buf[0] = 1000
    Allocated 8 bytes.  buf = 0x8049790, buf[-1] = 17, buf[-2] = 0, buf[0] = 1001
    Allocated 12 bytes.  buf = 0x80497a0, buf[-1] = 17, buf[-2] = 0, buf[0] = 1002
    Allocated 16 bytes.  buf = 0x80497b0, buf[-1] = 25, buf[-2] = 0, buf[0] = 1003
    Allocated 20 bytes.  buf = 0x80497c8, buf[-1] = 25, buf[-2] = 0, buf[0] = 1004
    Allocated 24 bytes.  buf = 0x80497e0, buf[-1] = 33, buf[-2] = 0, buf[0] = 1005
    Allocated 28 bytes.  buf = 0x8049800, buf[-1] = 33, buf[-2] = 0, buf[0] = 1006
    Allocated 100 bytes.  buf = 0x8049820, buf[-1] = 105, buf[-2] = 0, buf[0] = 1007
    sbrk(0) = 0x804a000
    
    So now the size information is in the first word before the pointer. It appears to be the size of the chunk plus one. You'll also note that malloc(12) allocates 16 bytes instead of 24. Why? Because it's only using four bytes for bookkeeping -- we pad to the next value of i such that i%8 = 4.

    Why then does malloc(4) allocate 16 bytes? Internal fragmentation I'm sure -- the size of a free list node has to be greater than 8 bytes.

    Here's the output on a DECstation running Ultrix in 2002:

    UNIX> fb4
    sbrk(0) = 0x10001100
    Allocated 4 bytes.  buf = 0x10005000, buf[-1] = 268435695, buf[-2] = 0, buf[0] = 1000
    Allocated 8 bytes.  buf = 0x10006000, buf[-1] = 268435951, buf[-2] = 0, buf[0] = 1001
    Allocated 12 bytes.  buf = 0x10006010, buf[-1] = 268435951, buf[-2] = 0, buf[0] = 1002
    Allocated 16 bytes.  buf = 0x10007000, buf[-1] = 268436207, buf[-2] = 0, buf[0] = 1003
    Allocated 20 bytes.  buf = 0x10007020, buf[-1] = 268436207, buf[-2] = 0, buf[0] = 1004
    Allocated 24 bytes.  buf = 0x10007040, buf[-1] = 268436207, buf[-2] = 0, buf[0] = 1005
    Allocated 28 bytes.  buf = 0x10007060, buf[-1] = 268436207, buf[-2] = 0, buf[0] = 1006
    Allocated 100 bytes.  buf = 0x10008000, buf[-1] = 268436719, buf[-2] = 0, buf[0] = 1007
    sbrk(0) = 0x10008ffc
    UNIX> 
    
    There's an odd one -- Any clues? When I turn the int's into shorts in fb5.c, I get:
     
    UNIX> fb5
    sbrk(0) = 0x10001100
    Allocated 4 bytes.  buf = 0x10005000, buf[-1] = 4096, buf[-2] = 239, buf[0] = 1000
    Allocated 8 bytes.  buf = 0x10006000, buf[-1] = 4096, buf[-2] = 495, buf[0] = 1001
    Allocated 12 bytes.  buf = 0x10006010, buf[-1] = 4096, buf[-2] = 495, buf[0] = 1002
    Allocated 16 bytes.  buf = 0x10007000, buf[-1] = 4096, buf[-2] = 751, buf[0] = 1003
    Allocated 20 bytes.  buf = 0x10007020, buf[-1] = 4096, buf[-2] = 751, buf[0] = 1004
    Allocated 24 bytes.  buf = 0x10007040, buf[-1] = 4096, buf[-2] = 751, buf[0] = 1005
    Allocated 28 bytes.  buf = 0x10007060, buf[-1] = 4096, buf[-2] = 751, buf[0] = 1006
    Allocated 100 bytes.  buf = 0x10008000, buf[-1] = 4096, buf[-2] = 1263, buf[0] = 1007
    sbrk(0) = 0x10008ffc
    UNIX> 
    
    Odd indeed. Can you guess at an explanation? I think I can, but I don't have the time to make sure it's correct. I'll talk about it in class.