C++ 标准多维数组内存布局
c++ std multidimensional array memory layout
定义多维标准数组时的内存布局是怎样的?
是单个连续的内存块还是指针数组?
例如-
const size_t M = 5;
const size_t N = 4;
int simple_2D_array[M][N];
std::array<std::array<int,N>,M> std_2D_array;
是否保证simple_2D_array和std_2D_array都和single continuous有相同的内存布局内存?
int simple_2D_array[M][N];
这保证在内存中是连续的。您可以使用指针算法来计算任何索引相对于开始的位置。
std::array<std::array<int,N>,M> std_2D_array;
一般来说,这在内存中不必是连续的。它是一个对象数组,每个对象恰好是一个数组。虽然每个内部数组作为其唯一的非静态数据成员在逻辑上等同于 C 风格数组,但允许编译器决定整个内部数组需要填充。
因此,在实践中,它可能是连续的,但依赖它可能并不值得。写一个迭代器什么的就可以了。
是的,但是...
首先,由于 std::array
只是普通数组的一个小包装,simple_2D_array
和 std_2D_array
将具有完全相同的内存布局。
接下来,该内存布局与大小为 20 的一维数组相同但是一维数组和任何二维数组之间会有很大差异一个
- 对于一维数组,声明的数组大小是对象的总大小:合法使用例如
arr[6]
.
- 对于 2D 对象,任何整数数组的声明大小仅为 4。从严格的语言角度来看,由于指针算法仅在数组中定义 它是将整个数组当作大小为 20 的一维数组来浏览是非法的(因此是未定义的行为)。
当然,任何常见的编译器都会接受它并产生预期的输出,因为它曾经是一种常见的习惯用法,拒绝它会破坏很多遗留代码。但它不是有效的 C++(我目前没有参考资料,但已经在 SO 上讨论过...)
定义多维标准数组时的内存布局是怎样的?
是单个连续的内存块还是指针数组?
例如-
const size_t M = 5;
const size_t N = 4;
int simple_2D_array[M][N];
std::array<std::array<int,N>,M> std_2D_array;
是否保证simple_2D_array和std_2D_array都和single continuous有相同的内存布局内存?
int simple_2D_array[M][N];
这保证在内存中是连续的。您可以使用指针算法来计算任何索引相对于开始的位置。
std::array<std::array<int,N>,M> std_2D_array;
一般来说,这在内存中不必是连续的。它是一个对象数组,每个对象恰好是一个数组。虽然每个内部数组作为其唯一的非静态数据成员在逻辑上等同于 C 风格数组,但允许编译器决定整个内部数组需要填充。
因此,在实践中,它可能是连续的,但依赖它可能并不值得。写一个迭代器什么的就可以了。
是的,但是...
首先,由于 std::array
只是普通数组的一个小包装,simple_2D_array
和 std_2D_array
将具有完全相同的内存布局。
接下来,该内存布局与大小为 20 的一维数组相同但是一维数组和任何二维数组之间会有很大差异一个
- 对于一维数组,声明的数组大小是对象的总大小:合法使用例如
arr[6]
. - 对于 2D 对象,任何整数数组的声明大小仅为 4。从严格的语言角度来看,由于指针算法仅在数组中定义 它是将整个数组当作大小为 20 的一维数组来浏览是非法的(因此是未定义的行为)。
当然,任何常见的编译器都会接受它并产生预期的输出,因为它曾经是一种常见的习惯用法,拒绝它会破坏很多遗留代码。但它不是有效的 C++(我目前没有参考资料,但已经在 SO 上讨论过...)