我正在尝试打印两个指针之间的距离,但我发现有时代码效果不佳。
Ellipse
尝试这种方法非常有效!!
#include <stdio.h>
#include <math.h>
/**
* Print the distance between 2 pointers
*/
void distance(int * a0, int * a1){
size_t difference = (size_t) a1 - (size_t) a0;
printf("distance between %p & %p: %u\n" ,a0, a1, abs((int) difference));
}
打印(示例):
int main(void){
int x = 100;
int y = 3000;
distance(&x, &y);
return 0;
}
但是这段代码开始出错了
distance between 0028ff18 & 0028ff14: 4
打印(示例):
int main(void){
int x = 100;
int p = 1500;
int y = 3000;
distance(&x, &y);
p = p + 2; // remove unused warning
// &p
return 0;
}
当必须打印distance between 0028ff18 & 0028ff14: 4
时,因为整数分隔了这些值!
但如果我取消评论8
,它又会再次发挥作用。
就好像变量//&p
在使用其内存地址之前不存在。
我在Windows 7(64位)上使用gcc 4.9.3
答案 0 :(得分:4)
p
未在您的计划中使用,可能会进行优化。无论如何,这是实现细节,编译器甚至可以自由地更改内存中x
和y
对象的顺序。
答案 1 :(得分:4)
就好像变量p在使用其存储器地址之前不存在
gcc将优化掉任何不影响程序行为的变量。
其次,你不能假设变量按照内存中的任何特定顺序排列,并且&#34;距离&#34;任何两个之间可能完全没有意义。只有当它们都指向同一个数组对象中的元素时,唯一可以依赖两个指针之间的距离才能产生任何意义的时间。
答案 2 :(得分:2)
指针算法仅在指向同一数组元素的指针之间有效,或者在结束之后有效。与此相反将产生不可预测和实现定义的结果。在这种情况下,您似乎自己找到了答案:gcc正在优化p
,但无论如何,您不能假设内存中任何特定的变量顺序,而是单独进行指针运算。
另外,这个:
size_t difference = (size_t) a1 - (size_t) a0;
应该是:
ptrdiff_t difference = a1 - a0;
两个指针之间差异的正确类型是ptrdiff_t
(在stddef.h
中定义)。您不应该将指针强制转换为size_t
,因为指针值不一定在size_t
中表示(如果您希望数字类型将指针转换为,请使用uintptr_t
或{{1} })。
intptr_t
格式说明符需要%p
,因此您应该转换指针,void *
的正确格式说明符为ptrdiff_t
:
%td