Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does malloc allocate a different number of bytes than requested?

I have this piece of code

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

int main(){
    void *a, *b;

    a = malloc(16);
    b = malloc(16);
    printf("\n   block size (for a): %p-%p : %li", b, a, b-a);

    a = malloc(1024);
    b = malloc(1024);
    printf("\n   block size (for a): %p-%p : %li", b, a, b-a);  
}

Shouldn't this print the last allocated block size (16 or 1024)? It instead prints 24 and 1032, so the amount of memory allocated seems to have 8 extra bytes.

My problem is (before making this test case) that I do malloc() in a function (1024 bytes), and return the allocated result. When checking the block size on the function return I get 516 blocks... and I don't understand why. I guess this might be the reason for the memory corruption that occurs after doing some processing on the allocated buffers:)

Edit: I've seen How can I get the size of an array from a pointer in C? and seems to ask the same thing, sorry for reposting.

I've redone my example to my more specific code:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

short int * mallocStuff(long int number, short int base){
    short int *array;
    int size=1024;

    array=(short int*)calloc(1,size);
    //array=(short int*)malloc(size);

    return array;
}

int main(){
    short int **translatedArray;

    translatedArray=malloc(4*sizeof(short int));

    int i;
    for(i=0;i<4;i++){
        translatedArray[i]=mallocStuff(0,0);

        if(i>0)
            printf("\n   block size (for a): %p-%p : %i",
                translatedArray[i], translatedArray[i-1], translatedArray[i]-translatedArray[i-1]);
    }

    return 0;
}

And the output is

   block size (for a): 0x804a420-0x804a018 : 516
   block size (for a): 0x804a828-0x804a420 : 516
   block size (for a): 0x804ac30-0x804a828 : 516

According to the above post that is bigger than 1024. Am I wrong?

like image 806
Quamis Avatar asked Jan 09 '09 23:01

Quamis


People also ask

How many bytes does malloc allocate?

Malloc(12) and malloc(16) allocate 16 bytes for the user, plus an extra 8 bytes for bookkeeping for a total of 24 bytes. Malloc(100) allocates 104 bytes for the user, plus an extra 8 bytes for bookkeeping.

Does malloc allocate bytes or bits?

Description: The malloc() function allocates a buffer of size bytes. Use free() or realloc() to free the block of memory. Because the malloc() implementation uses signed, 32-bit integers to represent the size internally, you can't allocate more than 2 GB in a single allocation.

What happens when malloc Cannot allocate the requested amount of memory?

If the malloc function is unable to allocate the memory buffer, it returns NULL. Any normal program should check the pointers which the malloc function returns and properly handle the situation when the memory allocation failed.

What happens if you malloc 0 bytes?

The malloc() function allocates size bytes and returns a pointer to the allocated memory. The memory is not initialized. If size is 0, then malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().


2 Answers

The malloc function always allocates slightly more than you ask for, in order to store some bookkeeping information. After all, when you call free() it needs to know how big the block is.

Also, generally malloc implementations will round the requested size up to the next multiple of 8 or 16 or some other round-ish number.

Update: The real answer to your question lies in your use of the short int type. When doing pointer arithmetic (subtraction) between typed pointers, C and C++ return the difference in the number of things pointed to. Since you are pointing to short int, which is two bytes in size, the value returned is half of what you are expecting.

On the other hand, malloc always allocates a given number of bytes, no matter what you cast the result to afterward. Try this:

    array=(short int*)malloc(sizeof(short int) * size);
like image 138
Greg Hewgill Avatar answered Oct 04 '22 02:10

Greg Hewgill


First, Malloc makes no guarantees that two successive malloc calls return successive pointers.

Second, depending on your specific architecture, different alignment rules apply; sometimes you might ask for a single byte, but the architecture prefers allocations on 8- or 4-byte intervals.

Third, malloc needs some overhead to store how big the allocated block is, etc.

Don't make assumptions about what malloc is doing past what the documentation says!

like image 35
SquareCog Avatar answered Oct 04 '22 02:10

SquareCog