【发布时间】:2016-12-16 17:30:24
【问题描述】:
据我所知,栈上的多维数组会按行顺序占用连续的内存。根据 ISO C++ 标准使用指向元素的指针来索引多维数组是未定义的行为吗?例如:
#include <iostream>
#include <type_traits>
int main() {
int a[5][4]{{1,2,3,4},{},{5,6,7,8}};
constexpr auto sz = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);
int *p = &a[0][0];
int i = p[11]; // <-- here
p[19] = 20; // <-- here
for (int k = 0; k < sz; ++k)
std::cout << p[k] << ' '; // <-- and here
return 0;
}
如果指针没有超出数组a 的边界,上述代码将正确编译并运行。但这是因为编译器定义的行为或语言标准而发生的吗?任何来自 ISO C++ 标准的参考都是最好的。
【问题讨论】:
-
嗯,我找不到任何与 ISO C++ 标准直接相关的内容。但是,是的,自动分配的数组保证连续存储在内存中。当您在简单指针上使用索引运算符(即
p[11])时,它等效于*(p+11),因此如果存在*p类型的合法数据,则定义行为。 -
我认为
[expr.add]/5可能会禁止这样做,但[dcl.array]/1确实保证存储是连续的。 -
@Yakk 从指针增量和索引运算符的定义中不言而喻。从技术上讲,C++ 标准保证,您只需成为一名律师即可正确阅读。多维数组是数组的数组(数组等)。因此,增加数组的索引会导致增量等于数组元素的大小,即子数组元素乘以子数组的长度……以此类推
-
@Swift 不,超过任何数组末尾的访问都是不合法的。即使你知道那里有什么。
-
@Swift 有一个由 4 个 5 个整数组成的数组。没有
int[20]类型的变量:20 个整数的数组。