请考虑以下代码:
int a[25][80];
a[0][1234] = 56;
int* p = &a[0][0];
p[1234] = 56;
Run Code Online (Sandbox Code Playgroud)
第二行是否调用未定义的行为?第四行怎么样?
c++ arrays pointers multidimensional-array undefined-behavior
是否在C++中使用未定义的行为来访问相邻数组中的元素,如下面的代码所示?
#include <type_traits>
#include <algorithm>
#include <iterator>
int main()
{
int a[10][10];
static_assert(std::is_standard_layout< decltype(a) >::value, "!");
std::fill(std::begin(*std::begin(a)), std::end(*std::prev(std::end(a))), 0);
struct B { int b[10]; };
B b[10];
static_assert(std::is_standard_layout< decltype(b) >::value, "!");
std::fill(std::begin(std::begin(b)->b), std::end(std::prev(std::end(b))->b), 0);
}
Run Code Online (Sandbox Code Playgroud)
从技术上讲,我认为对于POD类型来说,以任何方式访问底层内存是合法的,但是那些std::*东西呢?
如果我改变一切什么begin/end来rbegin/rend?
有很多像这样的代码:
#include <stdio.h>
int main(void)
{
int a[2][2] = {{0, 1}, {2, -1}};
int *p = &a[0][0];
while (*p != -1) {
printf("%d\n", *p);
p++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但基于这个答案,行为是不确定的.
N1570.6.5.6 p8:
当一个具有整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型.如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向偏离原始元素的元素,使得结果元素和原始数组元素的下标的差异等于整数表达式.换句话说,如果表达式P指向数组对象的第i个元素,则表达式(P)+ N(等效地,N +(P))和(P)-N(其中N具有值n)指向分别为数组对象的第i + n和第i-n个元素,只要它们存在.此外,如果表达式P指向数组对象的最后一个元素,则表达式(P)+1指向一个超过数组对象的最后一个元素,如果表达式Q指向一个超过数组对象的最后一个元素,表达式(Q)-1指向数组对象的最后一个元素.如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定义.如果结果指向数组对象的最后一个元素之后,则不应将其用作已计算的一元*运算符的操作数.
有人可以详细解释一下吗?