1

I've thought I understood pointers and pointers arithmetic but then I came across something unexpected to me. When I run this code I thought I was going to see "(header+1) - header = 32" as output. But I didnt. Can someone explain me why this was happened ?

    struct metadata *header = (struct metadata *)malloc(sizeof(struct metadata));
    printf("Struct size of : %d\n",sizeof(struct metadata));
    printf("header = %d header+1 = %d\n",header,header+1);
    printf("(header+1) - header = %d\n",(header+1) - header);

This gives the following output :

Struct size of : 32

header = 37704768 header+1 = 37704800

(header+1) - header = 1

Khan9797
  • 600
  • 1
  • 4
  • 12
  • X - X is 0 ... in general, isn't it. Also dare to explain why "*I thought I was going to see "(header+1) - header = 32"*"? – alk Dec 31 '17 at 16:14
  • The reason you get `1` is related to why you can't add two pointers in C. – Ted Hopp Dec 31 '17 at 16:16
  • @alk For example int *x = (int *)malloc(sizeof(int) * 10) will create an int array with 10 members. so whenever you want to access the fifth element you can use x[5] or *(x + 5) which are identical (or also &x[5] and (x + 5)) . So that x + 5 means actually adding sizeof(int)*5 to the beginning address of the array. So the sizeof(struct metadata) is 32 so you do the math :) And also If I casted int * to char * - such as ((char *)x + 5) it would only add 5 since sizeof(char) is always 1 byte. – Khan9797 Nov 05 '18 at 23:26

1 Answers1

2

From standard 6.5.6

When two pointers are subtracted, both shall point to elements of the same array object, or one past the last element of the array object; the result is the difference of the subscripts of the two array elements.

Here if you consider it an one element array, then two pointers - one of them are pointing to that element and 1 past the element. So that results in 1. The above rule obviously tells us that the result is scaled up by the sizeof the type that the pointers points to.

Also from same standard 6.5.6 where it is specified that 1 past the array element a pointer can point

Moreover, if the expression P points either to an element of an array object or one past the last element of an array object, and the expression Q points to the last element of the same array object, the expression ((Q)+1)-(P) has the same value as ((Q)-(P))+1and as -((P)-((Q)+1)), and has the value zero if the expression P points one past > the last element of the array object, even though the expression (Q)+1 does not point to an element of the array object

If I cast them into void *, I will get 32 right ?

Yes. it will be 32(if you are using gcc). sizeof(void)=1 (gcc makes it like that - not specified standard) but most probably other compiler will generate error which can be resolved by using char*.As sizeof char is 1 you can use char* casting to get the same result. As per standard this is not specified and illegal since void is an incomplete type.

Better to use char* casting to get the difference in bytes.

user2736738
  • 30,591
  • 5
  • 42
  • 56
  • Thanks, I didn't know that. – Khan9797 Dec 31 '17 at 16:22
  • If I cast them into void *, I will get 32 right ? Because there is no type defined in void as variable so they can't be the element of an array right ? – Khan9797 Dec 31 '17 at 16:32
  • 1
    @Khan9797 If you cast them to `char *`, you should get 32. Trying to subtract `void *` pointers is problematic, as arithmetic on `void *` pointers is undefined. (Pointer arithmetic always involves scaling by the size of the pointed-to object, and sizeof(void) is either undefined, or 0.) – Steve Summit Dec 31 '17 at 16:38
  • 1
    @Khan9797.: Edited my answer check once. – user2736738 Dec 31 '17 at 16:50