siliconwafer said:
Lets take an example:
char*str = (char*)malloc(1024);
printf("%d",sizeof(str));
what should get printed?
Let's fix your example:
char *str = malloc(1024);
printf("%d\n", (int)sizeof str);
The sizeof operator does not evaluate its operand; all it does is
yield its size in bytes. (There is an exception for VLAs
(variable-length arrays), but that's not relevant here.) So the fact
that you initialized str has no effect on the behavior of the code.
(You should normally check whether the malloc() succeeded, but that
doesn't matter here since you're not using the result.) So:
char *str;
printf("%d\n", (int)sizeof str);
The expression "sizeof str" yields the size in bytes of str, which is
the same as sizeof(char*). The standard says very little about what
this value will be. It's guaranteed to be at least 1; on some
systems, it can be 1. Certain other requirements imply that it needs
to be at least 16 bits in a hosted environment, so sizeof(char*)==1
implies CHAR_BIT>=16. If you don't understand these details yet,
don't worry about it.
There is very little guaranteed relationship between integers and
pointers. They are two entirely different things. A C pointer is
*not* some kind of integer in disguise; it's just a pointer. Its
value refers to some memory location, but the manner in which it does
so is implementation-specific. Different kinds of pointers can have
different sizes (though they tend to be the same on most systems).
You can convert integers to pointers and vice versa, but the results
of doing so are system-specific.
A pointer is not necessarily the same size as any particular integer
type; a system where pointers are 128 bits and the largest integer
type is 64 bits would be perfectly legal.
Pointers point to things. Forget everything else you think you know
about them, and start from there. Re-read the section on pointers in
your C textbook; if you don't have one, K&R2 is excellent. Read
section 4 of the C FAQ.
On a typical modern system, CHAR_BIT (the number of bits in a byte) is
likely to be 8, int is likely to be 32 bits, long is likely to be
either 32 or 64 bits, and pointers are likely to be 32 or 64 bits.
Converting a pointer to an unsigned integer of the same size is likely
to yield something that looks meaningful if you know anything about
the underlying memory addressing of the system. But the C standard is
designed to allow for exceptions to all of these things. You can
write useful code that doesn't depend on any of these assumptions, and
it will work everywhere, not just on "typical" systems.