Code:
int blah;
int foo[] = { 1, 2, 3, 4, 5 };
int *bar = malloc(sizeof(int) * 5);
Right. You just need to look directly at the types. In this case...

blah - int. 4 bytes of storage.

foo - array of 5 ints, which is 5 * 4. This is known by the compiler, and included directly into the stack, thus sizeof gives 20.

bar - pointer to int, which on a 32-bit machine is 4 bytes. It contains the memory location of where there is space allocated for 5 integers. Not the integers themselves. Sizeof takes the size of the pointer and returns it.


This is the main confusing thing in C, the differences between pointers and arrays. In fact, you could do bar = foo, and it would work properly. But the sizes would still be different. Arrays transparently decompose into pointers with almost any operation.

Oh, and the call to malloc() the compiler knows it's passing 20 to it, but as far as it's concerned, it's just another function...