David
David

Reputation: 2190

How does malloc distinguish between different types that both take up the same space?

Suppose the following program is run on an x86_64 system:

int main() {
    //sizeof(int) == 4
    //sizeof(int*) == 8
    //sizeof(long) == 8

    // I would like 2 distinct memory locations to hold these two integers
    int* mem1 = (int*)malloc(2 * sizeof(int));
    mem1[0] = 1;
    mem1[1] = 2;

    //I would like 1 distinct memory location to hold this one long
    long* mem2 = (long*)malloc(1 * sizeof(long));
    mem2[0] = 3;

    free(mem1);
    free(mem2);
    return 0;
}

Since malloc receives a number of bytes to allocate, both calls to malloc look exactly the same. How does malloc know to actually allocate 16 bytes to store the two integer array and only to allocate 8 bytes for the one long?

Edit for clarity: Based on the following assumptions, storing these two different arrays will require a different amount of space for each. However, malloc appears to reserve the same amount of space each time in this program. Yet, arrays sizes are correctly determined for arrays of datatypes of different lengths than longs.

Can someone help me identify a flaw in this understanding of the memory, or point to something that malloc / libc is doing in the background? Here are the assumptions I'm operating on

Upvotes: 0

Views: 183

Answers (4)

zoska
zoska

Reputation: 1723

malloc doesn't, but when you call mem[0] or mem[1] compilator knows what type is mem (int *mem) so when you're calling mem[1] it will know how much to increment mem pointer to access second element of this array. Distinction happens on compiler side.

Upvotes: 1

Stephen Canon
Stephen Canon

Reputation: 106197

The questioner was confused because he didn’t realize that char is the basic unit of memory in C. On his platform, sizeof(int) (which is the number of chars necessary to store an int) is 4. Thus, to store two ints, one needs to allocate 2*sizeof(int), or 8 bytes.

In the hypothetical world where long is the basic unit of memory (and sizeof(long) == 8), storing two ints really would require either packing or for 16 bytes to be allocated, but that’s not the way that C works.

Upvotes: 2

JackCColeman
JackCColeman

Reputation: 3807

You can always test your thesis with a some printf statements. For your example, use:

    printf("\nsizeof int is %d, long is %d", sizeof(int), sizeof(long));

and you will see that: 2*sizeof(int) == 1*sizeof(long).

Upvotes: 1

user529758
user529758

Reputation:

How does malloc distinguish between different types that both take up the same space?

It doesn't.

Since malloc receives a number of bytes to allocate, both calls to malloc look exactly the same. How does malloc know to actually allocate 16 bytes to store the two integer array and only to allocate 8 bytes for the one long

It can only use the size that you pass it as its argument. Your example and/or understanding is flawed, though - using the specified sizeof values, both calls will allocate 8 bytes. (That is, 2 * sizeof(int) which is 2 * 4, and sizeof(long), which is 1 * 8.)

Upvotes: 7

Related Questions