指针数学获取数组的长度 [英] Pointer math to get the length of an array

查看:107
本文介绍了指针数学获取数组的长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不认为这是重复的(见下文).


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


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


I know the usual method is to compute sizeof(array)/sizeof(*array) to get the number of elements in the array. (And it has been pointed out to me in comments that C++ has std::size(array).)

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

So, I reasoned that number could be calculated with pointer math if I could get to the address of one past the last element. But, then it occurred to me that I could:

&array + 1

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

But, the type of this value is pointer to array, so to allow the math to work, I would need to dereference this value.

const auto N = *(&array + 1) - array;

在C和C ++中是否存在允许这种取消引用合法的限制?

Is there an allowance in C and C++ that allows this dereference to be legal?

我知道允许您指向数组最后一个元素之后的一个,但不允许您取消引用它.但是,这种取消引用会产生一个数组对象,该对象立即衰减为指向其第一个元素的指针.

I know that you are allowed to point to one past the last element of an array, but you are not allowed to dereference it. However, this dereference yields an array object, which immediately decays to a pointer to its first element.

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

I could use a reinterpret_cast to avoid using the dereference operator, but I was wondering if the the C and/or C++ languages would allow the dereference in this case.

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

I missed a similar question, but this question is subtly different. I already understand how the code works, and I understand that there is normally a problem with dereferencing the pointer past the last element of the array. I am asking if the fact that array objects decay to a pointer when used in an expression allows for an exception. I think it might, because dereferencing a pointer to an object would normally result in the object value itself to be used in the expression (which would be a problem if the object does not exist).

推荐答案

不是. 这样做是未定义的行为:

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

Be aware, the expression *(&a + 1) results in undefined behavior:

...

...

如果结果指向数组对象的最后一个元素之后,则不应将其用作被评估的一元*运算符的操作数.

If the result points one past the last element of the array object, it shall not be used as the operand of a unary * operator that is evaluated.

C 2011在线草案, 6.5.6/9

C 2011 Online Draft, 6.5.6/9

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

So attempting to dereference something out of bounds will result in undefined behavior. No exceptions.

编辑:我可能错了.关于此问题,有一个另一个来源,您可以取消引用它(强调我的意思):

I might be wrong. There is a another source on this issue saying that you are able to dereference it (emphasis mine):

[注意:例如,数组末尾(5.7)的地址将被认为指向可能位于该地址的数组元素类型的不相关对象. —尾注]

[Note: for instance, the address one past the end of an array (5.7) would be considered to point to an unrelated object of the array’s element type that might be located at that address. —end note ]

在我看来,这暗示是,您可以合法地取消引用,但是读取或写入该位置的结果不确定.

Which seems to me to imply that yes, you can legally dereference it, but the result of reading or writing to the location is unspecified.

因此,由于它是过去的1指针(根据该作者),可以取消引用它,而不能读取或写入.在这种情况下,这不会对您造成影响,因为您正在将其用于其size属性.

So, because it is the 1 past pointer, (according to this author) it is okay to dereference it, just not read or write. In this case, this won't affect you since you are using it for its size properties.

请记住,在结束之后(相对于开始)超过1的任何内容都将无效.

Though, keep in mind, anything more than 1 after the end (as opposed to the beginning) and this won't work.

实际上,这是有争议的,甚至可能是由委员会本身提出的.尽管我不应该认为这里链接的问题与这一问题略有不同.

Actually, this is disputed, possibly even by the committee itself. Though I should not that the question linked here is slightly different than this one.

这篇关于指针数学获取数组的长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆