tags:

views:

153

answers:

2

I'm reading some code of a model malloc (allocateMemory). I have posted a portion of the code, but I couldn't understand the purpose of size = (size_in_bytes + sizeof(int) - 1) / sizeof(int); (The last line in the posted code)

void initializeHeap(void) {
    /* each chunk requires two signatures, one at the top and one
     * at the bottom, so the available space inside a chunk is 
     * the number of elements in the chunk minus 2
     */
    unsigned available_size = HEAP_SIZE - 2;

    if (initialized) { return; }


    /* write signatures at top and bottom of chunk */
    memory_pool[0] = available_size;
    memory_pool[HEAP_SIZE - 1] = available_size;
    initialized = true;
}

void* allocateMemory(unsigned size_in_bytes) {
    int size;
    unsigned chunk;
    int chunk_size;

    initializeHeap();

    size = (size_in_bytes + sizeof(int) - 1) / sizeof(int);
+1  A: 

It's rounding up the size to a multiple of sizeof(int). size will be the smallest number of ints that are larger than or equal to the space required by size_in_bytes.

Carl Norum
+7  A: 

It rounds the size up to a multiple of sizeof(int). This is normally done for alignment purposes since on some machines (for instance SPARC) you cannot access a 32-bit wide value that is aligned on an odd address (typical symptom is a SIGBUS). And even on processors that do support unaligned access, like x86 and PPC, it's often slower than an aligned access. It's also useful to help prevent cache splits, where half of the data is in one cache line and half is in another - this slows down access to the value by a factor of 2, which is pretty nasty.

Malloc has to assume the largest possible useful alignment because it does not know the size of the things it is allocating. Typically that is 4, 8, or 16 bytes, depending on the machine.

Jack Lloyd
Good answer, with one nitpick - `malloc()` does know the size of the thing it's allocating (it's told that), but it doesn't know the alignment requirement (which may be related to the size of members of the thing being allocated). For example, `int` and `struct { char a, b, c, d; }` may have the same size, but different alignment requirements. So `malloc()` typically needs to be written using a worst-case alignment for the target platform.
Michael Burr
Yeah I guess I worded it in a confusing way, by "size of the things" (should remember if I ever write "things" I'm probably being too vague) I meant "the size of each element", since of course malloc knows the total size of the requested block, it just doesn't know the size (or desirable alignment, which is not always the same thing but usually you can't go wrong aligning something of size N on an N byte boundary) of what is going to be placed into the block.
Jack Lloyd