subtracting two addresses giving wrong output

∥☆過路亽.° 提交于 2020-01-14 06:00:09

问题


int main()
{
    int x = 4;
    int *p = &x;
    int *k = p++;
    int r = p - k;
    printf("%d %d %d", p,k,p-k);
    getch();
}

Output:

2752116 2752112 1

Why not 4?

And also I can't use p+k or any other operator except - (subtraction).


回答1:


First of all, you MUST use correct argument type for the supplied format specifier, supplying mismatched type of arguments causes undefined behavior.

  • You must use %p format specifier and cast the argument to void * to print address (pointers)

  • To print the result of a pointer subtraction, you should use %td, as the result is of type ptrdiff_t.


That said, regarding the result 1 for the subtraction, pointer arithmetic honors the data type. Quoting C11, chapter §6.5.6, (emphasis mine)

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. The size of the result is implementation-defined, and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h> header. [....] if the expressions P and Q point to, respectively, the i-th and j-th elements of an array object, the expression (P)-(Q) has the value i−j provided the value fits in an object of type ptrdiff_t. [....]

So, in your case, the indexes for p and k are one element apart, i.e, |i-J| == 1, hence the result.


Finally, you cannot add (or multiply or divide) two pointers, because, that is meaningless. Pointers are memory locations and logically you cannot make sense of adding two memory locations. Only subtracting makes sense, to find the related distance between two array members/elements.

Related Constraints, from C11, chapter §6.5.6, additive operators,

For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to a complete object type and the other shall have integer type. (Incrementing is equivalent to adding 1.)




回答2:


What you are getting is the difference between the subscripts of two elements.
C11-6.5.6p9:

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.

Also note that the statement

 printf("%d %d %d", p,k,p-k);  

should be

printf("%p %p %ld\n", (void*)p,(void*)k, p-k);



回答3:


If your variable is of type pointer, then each calculation on pointer is done by multiplying of pointer type size.

For example:

//Lets assume char is 1 byte, int is 4 bytes long.
// sizeof(*cp) = 4, sizeof(*ip) = 4;
char *cp = (char *)10;  //Char itself is 1 byte
int *ip = (int *)10;
cp++;          //Increase pointer, let us point to the next char location
ip++;          //Increase pointer, let us point to the next int location

printf("Char: %p\r\n", (void *)cp); //Prints 11
printf("Int: %p\r\n", (void *)ip); //Prints 14

First case prints 11 while in second it prints 14. That's because next char element is 1 byte next, while next int element is 4 bytes in advance.

If you have 2 pointers of same type (eg. int *, like you) then if one points to 14 and another to 10, between is for 1 int memory, subtracting gives you 1.

If you want to get your result 4, then cast pointers to char * before calculation, because sizeof(char) is always 1 which means you have 4 elements between addressed 10 and 14 and you will get result 4.

Hope it helps.




回答4:


First of all adding 2 pointers is not defined. so if you use + operator, you will face compile error.

Second, the output is true and the if you minus 2 pointers, it shows how many boxes of that type are between the pointers. not the number of bytes.

You say :

int* p1 = &x;
int* p2 = p1++;

So between p1 & p2 there are 4 bytes. they are both of type int. so only 1 box of int is between them.



来源:https://stackoverflow.com/questions/44498435/subtracting-two-addresses-giving-wrong-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!