Reputation: 2190
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 long
s.
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
mem[idx]
refers to the address of mem plus the offset of idx, and that address cannot point to data in the middle of another item in memory (so mem1[0]
cannot refer to the lower half-word of mem1
and mem1[1]
can't then refer to the high word)Upvotes: 0
Views: 183
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
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 char
s necessary to store an int
) is 4. Thus, to store two int
s, 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 int
s really would require either packing or for 16 bytes to be allocated, but that’s not the way that C works.
Upvotes: 2
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
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