指针数学获取数组的长度

jxh*_*jxh 7 c c++ arrays pointers language-lawyer

我不相信这是重复的(见下文)。†


我发现这个问题几乎是一个精确的重复,但是我认为答案无法分析漏洞。请参阅:*((*(&array + 1))-1)`是否可以安全地用于获取自动数组的最后一个元素?


我知道通常的方法是计算sizeof(array)/sizeof(*array)以获取数组中元素的数量。(并且在注释中已向我指出C ++具有std::size(array)。)

因此,我认为如果可以到达最后一个元素之后的地址,则可以使用指针数学运算来计算该数字。但是,后来我想到我可以:

&array + 1
Run Code Online (Sandbox Code Playgroud)

但是,此值的类型是指向数组的指针,因此要使数学正常工作,我需要取消引用此值。

const auto N = *(&array + 1) - array;
Run Code Online (Sandbox Code Playgroud)

在C和C ++中是否有允许这种取消引用合法的津贴?

我知道您可以指向数组最后一个元素之后的一个,但是您不能取消引用它。但是,此取消引用会产生一个数组对象,该对象立即衰减为指向其第一个元素的指针。

我可以使用a reinterpret_cast来避免使用取消引用运算符,但是我想知道在这种情况下C和/或C ++语言是否允许取消引用。


†我错过了类似的问题,但是这个问题有细微的不同。我已经了解了代码的工作原理,并且了解了将指针从数组的最后一个元素后移去通常存在问题。我要问的是,数组对象在表达式中使用时会衰减为指针的事实是否允许例外。我认为这可能是因为,取消引用指向对象的指针通常会导致对象值本身在表达式中使用(如果对象不存在,这将是一个问题)。

小智 4

没有。这样做是未定义的行为:

\n\n
\n

请注意,表达式 *(&a + 1) 会导致未定义的行为:

\n\n
\n

...

\n\n

如果结果指向数组对象的最后一个元素,则不得将其用作所计算的一元 * 运算符的操作数。

\n
\n\n

C 2011在线草案,6.5.6/9

\n
\n\n

因此,尝试取消引用超出范围的内容将导致未定义的行为。没有例外。

\n\n
\n\n

编辑:我可能是错的。关于这个问题还有另一个消息来源说你可以取消引用它(强调我的):

\n\n
\n
\n

[注意:例如,超出数组末尾的地址 (5.7) 将被视为指向可能位于该地址的 array\xe2\x80\x99s 元素类型的不相关对象。\xe2\x80\x94结束注]

\n
\n\n

在我看来,这意味着是的,您可以合法地取消引用它,但读取或写入该位置的结果未指定。

\n
\n\n

因此,因为它是 1 个过去的指针,(根据该作者的说法)可以取消引用它,只是不读取或写入。在这种情况下,这不会影响您,因为您正在使用它的大小属性。

\n\n

不过,请记住,结束后(而不是开始)超过 1 的任何内容都将不起作用。

\n\n
\n\n

事实上,这一点是有争议的,甚至可能是委员会本身。虽然我不应该认为这里链接的问题与这个问题略有不同。

\n


归档时间:

查看次数:

190 次

最近记录:

6 年,10 月 前