似乎有一种语言特定于将一个的地址多于数组末尾。
为什么 2 或 2,000,000 在结束时会出现问题,如果它没有被解除引用?
看一些简单的循环:
int array[];
...
for (int i = 0: i < array_max; ++i)
{
int * x = &array[i *2]; // Is this legal
int y=0;
if (i * 2 < array_max) // We check here before dereference
{
y = *x; // Legal dereference
}
...
}
为什么或在什么时候这变得未定义,在实践中它只是将ptr设置为某个值,为什么如果它没有被重新引用它将是未定义的?
更具体地说 - 除了预期会发生什么之外,还有什么例子?
答案 0 :(得分:8)
使用超出数组末尾的地址的关键问题是分段体系结构:您可能溢出指针的可表示范围。现有规则已经产生了一定程度的痛苦,因为这意味着最后一个对象不能正好在一个段的边界上。但是,形成这个地址的能力已经确立。
答案 1 :(得分:4)
由于array[i *2]
等同于*((array) + (i*2))
,我们应该查看指针添加的规则。 C ++11§5.7说:
如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出;否则,行为未定义。
所以你有未定义的行为,即使你没有对指针执行间接(更不用说你做执行间接,因为我在开头给出的表达式等价)。
答案 2 :(得分:3)
在实践中它只是将ptr设置为某个值
理论上,不允许使用指向某处无效的指针。
指针不整数:它们是指向其他内容或无效的内容。
您不能将它们设置为您喜欢的任何数字。
在这个例子中,只有赋值,然后是限定的dereferrencing - 该值仅在验证时使用,问题是为什么值的设置是个问题?
是的,你必须非常不幸遇到这样做的实际后果。 “未定义的行为”不意味着“总是崩溃”。为什么标准实际上要求这种操作的语义?您认为这种语义应该是什么?