tags:

views:

87

answers:

4

Below is the program to find the size of a structure without using sizeof operator:

struct MyStruct
{
  int i;
  int j;
};

int main()
{
   struct MyStruct *p=0;
   int size = ((char*)(p+1))-((char*)p);
   printf("\nSIZE : [%d]\nSIZE : [%d]\n", size);
   return 0;
}

My doubt is:

Why is typecasting to char * required?

If I don't use the char* pointer, the output is 1 - WHY?

+2  A: 

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.

Tyler McHenry
+2  A: 

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?

Billy ONeal
And if you do use `sizeof` be sure to use it on the pointed-to object, not the pointer itself. `sizeof(p)` will give you the size of a pointer, where as `sizeof(*p)` will give you the size of a `MyStruct`.
Tyler McHenry
+2  A: 

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.

Nikola Smiljanić
Well, `sizeof` return the size in units of whatever a `char` is stored in (i.e. sizeof(char) is always 1). That's bytes in typical implementations, but is not required to be so...
dmckee
That is true, but whenever you ask for a byte type you get the answer unsigned char :)
Nikola Smiljanić
+1  A: 

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.

Jerry Coffin