2014-02-17 66 views
3

this thread中,它使用&x + 1来确定一些随机结构x的大小。我想知道为什么这是一个合法的解决方案?这会造成分段错误吗?为什么x + 1不会导致seg故障?

我的理解是,只要&x + 1保持当前线程访问的存储器内,这将是好的,但如果&x + 1莫名其妙试图访问其允许范围之外的一块内存,就会造成赛格故障,是那对吗?

回答

6

第三,C标准明确允许指针指向一个数组的末尾。

...如果指针操作数和结果指向 同一阵列对象,或一个过去的数组对象的最后一个元素的元素两者, 评价不得产生溢出...

正如@alk所指出的,在做指针运算时,一个指针到一个对象被当作长度1.

的阵列对于这些操作符的目的,一个指针到一个对象,该对象是 不是数组元素的行为与第一个 元素的指针的行为相同,该元素的长度为一个数组,其元素类型为对象的类型 元素类型。

(从第6.5.6.8和C99草案here的6.5.6.7)

+0

是的,但我们正在处理单个对象,而不是数组。 – user763305

+6

@ user763305:C99 6.5.6/7:“*就这些[additive]运算符而言,指向非数组元素的对象的指针的行为与指向数组的第一个元素的指针相同*“ – alk

+0

alk:谢谢。我只是学习新的东西。 – user763305

5

首先,在C中,所有线程都可以访问任何线程可以访问的所有内存。线程在这里不是问题。

其次,您从不取消引用&x + 1的指针,所以您无论如何都不访问任何内存。

所以你的代码是正确的。

+1

访问未分配存储器引发未定义的行为。它不是“*不是解除引用*”,而是“+ 1”,它具有魔力。用'n> 1'做'&x + n'也会引发未定义的行为,即使不解引用结果,读指针就足够了。请参阅上面的* AShelly *的回答:http://stackoverflow.com/a/21837091/694576 – alk

+2

这是不正确的,为什么'&x + 1'没问题。 “不访问任何内存”将会避免出现问题。实际的原因是C标准允许将一个指针递增到超出数组末尾的指针(包括一个对象,该对象被视为一个元素的数组)。如果表达式是'&x + 2',程序可能会崩溃。每个C 2011(N1570)6.5.6 8:“如果指针操作数和结果指向同一个数组对象的元素,或者一个超过数组对象的最后一个元素,则评估不应产生溢出;否则,行为是不确定的。“ –

+0

Eric Postpischil:那么'(&x + 2) - 1'可能会导致程序崩溃? – user763305