使用nullptr计算指针偏移是否安全?

时间:2014-07-22 14:21:47

标签: c++ memory c++11 nullptr

假设我有两个指针:

char* p1 = nullptr;
char* p2 = std::malloc( 4 );
std::size_t offset = p2 - p1;

以这种方式获得抵消是否安全?到目前为止它在我的电脑上工作正常。但我想知道偏移是否可以超过size_t的最大数量,以致此方法失败?

3 个答案:

答案 0 :(得分:6)

这是未定义的行为,来自draft C++ standard部分5.7 添加剂运算符

  

当减去指向同一数组对象的元素的两个指针时,   结果是两个数组的下标的差异   元素。结果的类型是实现定义的签名   积分型;此类型应与定义的类型相同   标题中的std :: ptrdiff_t(18.2)。 [...]除非两者兼而有之   指针指向同一个数组对象的元素,或者指向一个数组对象的元素   数组对象的最后一个元素,行为是   未定义。 82

同样如参考文献所述,结果为std::ptrdiff_t而不是size_t

另一方面,您可以添加或减去 7 段落中涵盖的值0

  

如果将值0添加到指针值或从指针值中减去,则   result compare等于原始指针值。如果有两个指针   指向同一个对象或两者都指向同一个对象的末尾   数组或两者都为null,并且减去两个指针   result compare等于转换为类型的值0   的std :: ptrdiff_t的。

如果要将指针转换为整数值,则应使用intptr_t or uinitptr_t

intptr_t   integer type capable of holding a pointer
uintptr_t  unsigned integer type capable of holding a pointer

例如:

uintptr_t ip = reinterpret_cast<uintptr_t>( p2 ) ;

答案 1 :(得分:3)

不,这不安全。基本上你可以用空指针做的唯一事情是将它与另一个指针进行比较。对于加法和减法,只能向空指针添加或减去零,并减去两个空指针 - 这在通用编程中可能很有用。您的案例是未定义的行为。

答案 2 :(得分:3)

除了Wojtek的答案之外,指针算法只能在相关指针之间进行。例如,如果您有例如char* p3 = p2 + 4,那么你可以p3 - p2来获得两个指针之间的区别,这是合法的。

然而,像

这样的事情
char* p4 = new char[4];
std::cout << p4 - p2 << '\n';

合法,因为p2p4不是相关的