C ++中动态二维数组中的地址
address in dynamic two dimensional array in c++
我可以通过以下方式在 C++ 中创建一个二维数组。但是我无法理解内存寻址。
(请注意我的代码的最后一行,我在其中尝试打印内存位置的十进制值。)
#include <cstdio>
#include <iostream>
using namespace std;
#define rowSize 3
#define colSize 4
int main(){
int ** p;
p = new int*[rowSize];
for(int i = 0; i < rowSize; i++){
p[i]= new int[colSize];
}
printf("the size of int**: %d\n", sizeof(int**));
printf("the size of int*: %d\n", sizeof(int*));
printf("the size of int: %d\n\n", sizeof(int));
printf("%d %d", p[0], p[1]);
return 0;
}
我在 windows 10-64 位机器上使用了 gcc 版本 4.7.1 (tdm-1) 编译器和 运行 我的程序。
这是一个示例输出:
the size of int**: 4
the size of int*: 4
the size of int: 4
8135000 8135024
所以,这是我的两个问题:
为什么地址相差 24 而不是 16 (= 4*4)?
int 的大小为 4,一行中有 4 列。那么他们不应该相差16吗?
我知道 c++ 结构中的字节填充。是这样的原因吗?
我尝试将 colSize 更改为 5:
#define colSize 5
并重新编译 运行 程序。
示例输出:
the size of int**: 4
the size of int*: 4
the size of int: 4
7151960 7151992
这次地址相差 32。如果字节填充是原因,5 列将需要 5*4 = 20 个字节。在这种情况下填充 4 个字节就足够了,在这种情况下地址也应该相差 24。
那么为什么在这种情况下它们相差 32?
您不是在编写 C++,而是在编写 C。由于您将此标记为 C++,因此我假设您需要 C++...
现代 C++ 使用 RAII 并通过使用库标准容器大大简化了这类事情。虽然我知道这并不是您问题的真正答案,但我还是建议您重写代码:
#include <vector>
#include <cstdio>
int main()
{
int rowsize = ...;
int colsize = ...;
// allocating
std::vector<std::vector<int>> vec(rowsize);
for( auto e: vec )
e.resize(colsize);
// filling with values
vec.at(row).at(col) = 123;
// printing values
std::cout << vec.at(row).at(col) << std::endl;
}
您的 p[i]
arryas 单元格中的地址由 new
运算符定义
p[i]= new int[colSize];
此运算符可以 return 堆中的任何地址,这与数组大小无关。
您可以创建一个大的一维数组(就像编译器所做的那样array[][]
)并将二维映射到一维。
int* arr2d = new int[colSize*rowSize];
//Retrieve value from Row3 Col2
int nRow3Col2 = arr2d[2 + 3 * colSize];
- 内存分配操作的结果是
alignof(std::max_align_t)
对齐的。在你的情况下 alignof(std::max_align_t)
可能是 8.
- 在大多数实现中,有一个不可见的
sizeof(std::max_align_t)
字节与数组一起分配,用于一些内部簿记。在您的情况下,它的大小可能为 8。
所以在第一种情况下:4*4 + 8 = 24,已经是 8 的倍数了。
第二个:4*5 + 8 = 28,四舍五入到最接近的 8 = 32 的倍数。
编译器没有义务return增加地址或遵循某种模式。碰巧在你的情况下这是最简单的事情。
我可以通过以下方式在 C++ 中创建一个二维数组。但是我无法理解内存寻址。
(请注意我的代码的最后一行,我在其中尝试打印内存位置的十进制值。)
#include <cstdio>
#include <iostream>
using namespace std;
#define rowSize 3
#define colSize 4
int main(){
int ** p;
p = new int*[rowSize];
for(int i = 0; i < rowSize; i++){
p[i]= new int[colSize];
}
printf("the size of int**: %d\n", sizeof(int**));
printf("the size of int*: %d\n", sizeof(int*));
printf("the size of int: %d\n\n", sizeof(int));
printf("%d %d", p[0], p[1]);
return 0;
}
我在 windows 10-64 位机器上使用了 gcc 版本 4.7.1 (tdm-1) 编译器和 运行 我的程序。
这是一个示例输出:
the size of int**: 4
the size of int*: 4
the size of int: 4
8135000 8135024
所以,这是我的两个问题:
为什么地址相差 24 而不是 16 (= 4*4)? int 的大小为 4,一行中有 4 列。那么他们不应该相差16吗? 我知道 c++ 结构中的字节填充。是这样的原因吗?
我尝试将 colSize 更改为 5:
#define colSize 5
并重新编译 运行 程序。示例输出:
the size of int**: 4 the size of int*: 4 the size of int: 4 7151960 7151992
这次地址相差 32。如果字节填充是原因,5 列将需要 5*4 = 20 个字节。在这种情况下填充 4 个字节就足够了,在这种情况下地址也应该相差 24。
那么为什么在这种情况下它们相差 32?
您不是在编写 C++,而是在编写 C。由于您将此标记为 C++,因此我假设您需要 C++...
现代 C++ 使用 RAII 并通过使用库标准容器大大简化了这类事情。虽然我知道这并不是您问题的真正答案,但我还是建议您重写代码:
#include <vector>
#include <cstdio>
int main()
{
int rowsize = ...;
int colsize = ...;
// allocating
std::vector<std::vector<int>> vec(rowsize);
for( auto e: vec )
e.resize(colsize);
// filling with values
vec.at(row).at(col) = 123;
// printing values
std::cout << vec.at(row).at(col) << std::endl;
}
您的 p[i]
arryas 单元格中的地址由 new
运算符定义
p[i]= new int[colSize];
此运算符可以 return 堆中的任何地址,这与数组大小无关。
您可以创建一个大的一维数组(就像编译器所做的那样array[][]
)并将二维映射到一维。
int* arr2d = new int[colSize*rowSize];
//Retrieve value from Row3 Col2
int nRow3Col2 = arr2d[2 + 3 * colSize];
- 内存分配操作的结果是
alignof(std::max_align_t)
对齐的。在你的情况下alignof(std::max_align_t)
可能是 8. - 在大多数实现中,有一个不可见的
sizeof(std::max_align_t)
字节与数组一起分配,用于一些内部簿记。在您的情况下,它的大小可能为 8。
所以在第一种情况下:4*4 + 8 = 24,已经是 8 的倍数了。
第二个:4*5 + 8 = 28,四舍五入到最接近的 8 = 32 的倍数。
编译器没有义务return增加地址或遵循某种模式。碰巧在你的情况下这是最简单的事情。