【问题标题】:Is pointer arithmetic in iterations overflow-safe?迭代中的指针算术溢出安全吗?
【发布时间】:2013-10-02 05:05:56
【问题描述】:

即使在较新的 C++ 代码中,我也经常看到使用普通指针算法的数组迭代。我想知道它们到底有多安全,以及使用它们是否是个好主意。考虑一下这个 sn-p(如果你用 calloc 代替 new,它也可以在 C 中编译):

int8_t *buffer = new int8_t[16];
for (int8_t *p = buffer; p < buffer + 16; p++) {
    ...
}

buffer发生分配到地址0xFFFFFFF0(在32位地址空间中)或@时,这种迭代不会导致溢出和循环被完全跳过吗? 987654326@(64 位)? 据我所知,这将是一个非常不走运但仍有可能发生的情况。

【问题讨论】:

  • 是的,在这种情况下可能会导致溢出。但无论如何,没有一个健全的操作系统会为你在这些地址映射内存。
  • 是指针溢出定义的行为吗?
  • @JoachimPileborg 对此有保证吗?
  • 我会使用直接不等式而不是“小于”。 IE。 p != (buffer + 16) 对于您正在做的事情是可以接受的。
  • @Dave 因为 0xFFFFFFF0 == 0x0 在你的装备上?

标签: c++ c iteration pointer-arithmetic


【解决方案1】:

这是安全的。 C 和 C++ 标准明确允许您计算指向超出数组末尾的一项的指针值,并将指向数组内的指针与该值进行比较。

在您描述的情况下存在溢出问题的实现根本不允许像那样将数组放在内存的末尾。

在实践中,一个更可能的问题是buffer + 16 比较等于NULL,但这也是不允许的,并且再次符合要求的实现需要在数组末尾留下一个空白位置。

【讨论】:

  • 今晚我脑子里有雾。标准中是否指出了指针类型的较小比较?我知道平等和不平等是,但老实说不记得其他关系操作。
  • @WhozCraig 关系运算符是为指针类型定义的,但它们只允许将指针比较到同一个数组中,否则它是未定义的行为。
  • @Simple 罗杰。我刚刚在 C99 §6.5.8,p5 中找到它,包括您提到的关于驻留在同一数组区域中的特异性。我假设 C++ 中也有类似的规范。
  • @WhozCraig:由于p总是在分配范围之内,所以&lt;和朋友们定义明确。
  • @WhozCraig: 5.9 p2 最后一句:“如果两个指针指向同一个数组的元素或一个超出数组末尾的元素,则指向具有较高下标的对象的指针比较高。”
猜你喜欢
  • 2011-07-15
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多