如果最后一个地址是0xFFFFFFFF,如何取一个数组末尾的地址?

时间:2011-12-04 22:44:03

标签: c++

如果将地址取一个数组的末尾是合法的,如果数组地址的最后一个元素是0xFFFFFFFF,我该怎么做呢?

这段代码如何运作:

for (vector<char>::iterator it = vector_.begin(), it != vector_.end(); ++it)
{
}

编辑:

我在这里读到,在提出这个问题之前这是合法的:May I take the address of the one-past-the-end element of an array?

7 个答案:

答案 0 :(得分:9)

如果这种情况对于特定体系结构(它可能是也可能不是)是一个问题,那么可以期望编译器和运行时安排分配的数组永远不会在0xFFFFFFFF结束。如果他们没有做到这一点,并且当一个数组 在那里结束时某些东西就会中断,那么它们将不符合C ++标准。

答案 1 :(得分:3)

访问数组边界是未定义的行为。如果一个恶魔飞出你的鼻子,你不应该感到惊讶(或类似的东西)

实际可能发生的是地址溢出,这可能导致您读取地址为零,从而导致分段错误。

如果你总是在数组范围内,并且你从数组中取出最后一个++it并将它与_vector.end()进行比较,那么你实际上并没有访问任何内容而且不应该是个问题。

答案 2 :(得分:1)

  • 该代码实际上访问该地址。
  • 并且你永远不会在真实系统上为你的对象获得这样的地址。

答案 3 :(得分:1)

我认为有一个很好的论据可以证明符合条件的C实现不允许数组以(例如)0xFFFFFFFF结束。

p成为指向数组的一个元素的指针:如果buffer被声明为char buffer[BUFFSIZE],那么p = buffer+BUFFSIZEp = &buffer[BUFFSIZE]。 (后者的含义相同,其有效性在C99标准文件中明确说明。)

然后我们期望指针比较的普通规则起作用,因为p的初始化是指针算术的普通位。 (你无法比较标准C中的任意指针,但如果它们都基于单个数组,内存缓冲区或结构,你可以比较它们。)但如果buffer以0xFFFFFFFF结束,则p会是0x00000000,我们会遇到p < buffer

的不太可能的情况

这将破坏许多现有代码,这些代码假设在相对于数组库完成的有效指针算法中,直观的地址排序属性成立。

答案 4 :(得分:0)

区别在于取消引用该元素并获取其地址。在您的示例中,结尾的元素不会被解除引用,因此它是有效的。虽然在C ++的早期阶段并不是很清楚,但现在已经很清楚了。您传递给下标的值也无关紧要。

答案 5 :(得分:0)

有时你可以对角落案件做的最好的事情是禁止他们。我在NS32032的一些位字段提取指令中看到了这类问题,其中硬件将从字节地址开始加载32位并从该数据中提取。因此,即使映射内存的最后3个字节中的任何位置的单位字段也会失败。解决方案是永远不允许最后4个字节的内存可用于分配。

答案 6 :(得分:0)

相当多的受此影响的体系结构通过为操作系统保留偏移量0xFFFFFFFF(以及更多)来解决问题。