Why does my homespun sizeof operator need a char* cast?
Below is the program to find the size of a structure without using sizeof operator:
struct MyStruct
{
int i;
int j;
};
int main()
{
struct MyS开发者_如何学Ctruct *p=0;
int size = ((char*)(p+1))-((char*)p);
printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);
return 0;
}
Why is typecasting to char * required?
If I don't use the char* pointer, the output is 1 - why?
Because pointer arithmetic works in units of the type pointed to. For example:
int* p_num = malloc(10 * sizeof(int));
int* p_num2 = p_num + 5;
Here, p_num2
does not point five bytes beyond p_num
, it points five integers beyond p_num
. If on your machine an integer is four bytes wide, the address stored in p_num2
will be twenty bytes beyond that stored in p_num
. The reason for this is mainly so that pointers can be indexed like arrays. p_num[5]
is exactly equivalent to *(p_num + 5)
, so it wouldn't make sense for pointer arithmetic to always work in bytes, otherwise p_num[5]
would give you some data that started in the middle of the second integer, rather than giving you the sixth integer as you would expect.
In order to move a specific number of bytes beyond a pointer, you need to cast the pointer to point to a type that is guaranteed to be exactly 1 byte wide (a char
).
Also, you have an error here:
printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);
You have two format specifiers but only one argument after the format string.
If I don't use the char* pointer, the output is 1 - WHY?
Because operator-
obeys the same pointer arithmetic rules that operator+
does. You incremented the sizeof(MyStruct)
when you added one to the pointer, but without the cast you are dividing the byte difference by sizeof(MyStruct)
in the operator-
for pointers.
Why not use the built in sizeof()
operator?
Because you want the size of your struct in bytes. And pointer arithmetics implicitly uses type sizes.
int* p;
p + 5; // this is implicitly p + 5 * sizeof(int)
By casting to char* you circumvent this behavior.
Pointer arithmetic is defined in terms of the size of the type of the pointer. This is what allows (for example) the equivalence between pointer arithmetic and array subscripting -- *(ptr+n)
is equivalent to ptr[n]
. When you subtract two pointers, you get the difference as the number of items they're pointing at. The cast to pointer to char
means that it tells you the number of chars between those addresses. Since C makes char
and byte
essentially equivalent (i.e. a byte is the storage necessary for one char) that's also the number of bytes occupied by the first item.
精彩评论