一个对象如何接近最大指针值以避免溢出?

时间:2016-07-21 10:48:55

标签: c++ pointers

有效指针有多接近最大值(作为全局,在堆栈上分配,mallocnewVirtualAlloc或任何其他alloc方法/程序/库可能会使用),这样ptr + n冒着溢出的风险?

我遇到了很多代码,在处理字符串/数组时会为指针添加值(在C ++中,有时也在通用的“随机访问迭代器”模板函数中)。

e.g。

auto end = arr_ptr + len; //or just whatever some_container.end() returns
for (auto i = begin; i < end; ++i) { ... }
for (auto i = begin; i + 2 <= end; i += 2) { ...i[0]...i[1]... }
if (arr_ptr + 4 <= end && memcmp(arr_ptr, "test", 4) == 0) { ... }
if (arr_ptr + count > end) resize(...);

最后一个数组元素在0xFFFFFFFF(假设为32位)结束时是否有效,这样end == 0?如果没有,它有多接近?

我认为始终使用p != end(并且只添加1)或将长度设为len = end - begin然后使用它(例如(end - begin) >= 4)总是安全的,但想知道它是否真的要注意的问题,并审核和更改现有代码。

1 个答案:

答案 0 :(得分:3)

标准没有讨论指针溢出,它讨论了指针运算可以合法地形成什么指针值。简单地说,合法的范围是指向你的对象/数组的指针加上一个过去的指针。

然后,C或C ++实现的责任是不在某些特定于实现的危险(如指针溢出)阻止那些合法指针值正常工作的位置创建任何对象。

因此,malloc等,也不是堆栈(假设你没有超过任何堆栈边界)将给你一个char数组,从你不能到达的地址开始(到期)溢出)添加数组的大小。

  

它有多接近?

尽可能允许所有必需的指针值正常工作。因此,在这个32位系统上,从0xFFFFFFFE开始的1字节对象将是最大可能地址。该标准不允许您将2添加到地址,因此它并不重要&#34;就实施而言,这样做会溢出。对于一个2字节的对象,如果类型是未对齐的,则最大值为0xFFFFFFFD,但这是一个奇数,所以0xFFFFFFFC如果它需要2对齐。

当然,其他实施细节可能会规定下限。例如,系统在0的任一侧保留一页内存并使其无法访问并不罕见。这有助于捕获有人访问具有小偏移量的空指针的错误。当然,这更可能发生在正偏移而非负面,但仍然如此。如果您的32位系统决定这样做,那么malloc需要考虑它,并且永远不会返回0xFFFFFFFE