假设我有两个指针:
char* p1 = nullptr;
char* p2 = std::malloc( 4 );
std::size_t offset = p2 - p1;
以这种方式获得抵消是否安全?到目前为止它在我的电脑上工作正常。但我想知道偏移是否可以超过size_t的最大数量,以致此方法失败?
答案 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';
不 合法,因为p2
和p4
不是相关的。