我正在学习c ++并在书中找到了这个
array_ptr = new int[3][5][4];
这用于使用new将内存分配给多维数组。它还说明第一维可以是一个变量,其值在运行时提供,其他变量必须是常量。 我试着运行这段代码
int *p = new int[3][5][6];
但它显示错误。 有人可以详细说明。
答案 0 :(得分:2)
这是你想要的:
int (*p)[5][6] = new int[3][5][6];
从C ++ 11开始,您可以要求编译器为您解释p
的类型:
auto p = new int[3][5][6];
你不需要任何特殊的东西来删除这样的数组:
delete [] p;
选择类型背后的逻辑很简单:
在此行中:int *p = new int[10]
您正在创建array of 10 ints
并使用pointer to int
来存储地址。
一般情况下,如果您要分配array of N Ts
(其中N
是大小且T
是类型),则使用pointer to T
存储地址。
同样的规则可以应用于多维数组,因为它们实际上是嵌套的1D数组。
当您尝试分配多维数组:p = new int[4][5][6]
时,您正在创建array of 4 arrays of 5 arrays of 6 ints
。因此,您需要pointer to array of 5 arrays of 6 ints
,即int (*p)[5][6]
。
换句话说,int [3][4][5]
可以被视为大小为3
的一维数组。它由int [4][5]
类型的其他数组组成。这些数组中的每一个都具有4
的大小,并且由int [5]
类型的其他数组组成,而这些数组又包含5
int
s。
P.S。其他答案的作者似乎赞成使用int ***
并分别为每个嵌套数组分配内存。这样做可能看起来很聪明,但实际上它更慢且更危险(如果你弄乱你的内存管理)。该技巧的唯一优势是它提供了我们习惯使用的方便界面(p[z][y][x]
)。
但是有一个更好的解决方案:int *p = new int[x_sz * y_sz * z_sz];
。您需要将3D索引转换为1D索引(p[x + x_sz * (y + z * y_sz)]
而不是p[z][y][x]
)才能使其正常工作,但在我看来它更方便(并且肯定更快)。
当然,在实际代码中,您应该使用std::vector
来存储这样的数组和编写自己的包装类,这将自动计算索引。
答案 1 :(得分:-1)
3d数组与指向int的指针不同,你不能使它们相同。
如果需要动态分配,可以使用特殊类std::vector
(最佳选择),std::array
或编写下一个代码:
int ***p = new int**[3];
for (int i = 0; i < 3; ++i) {
p[i] = new int*[5];
for (int j = 0; j < 5; ++j) {
p[i][j] = new int[6];
}
}
答案 2 :(得分:-1)
为了创建动态3d数组,你必须使用指向指针的指针)
const int xSize = 3;
const int ySize = 5;
const int zSize = 4;
int*** p = nullptr;
// creating array of pointers to pointers
p = new int** [xSize]
// for each pointer to pointers, create array of pointers
for( int i = 0; i < xSize; ++i )
p[ i ] = new int* [ySize];
// now we have 2d array of pointers, for each of them allocate array
for( int i = 0; i < xSize; ++i )
for( int j = 0; j < ySize; ++j )
p[ i ][ j ] = new int [zSize];
但是使用矢量要好得多
vector<vector<vector<int> > > v3d;
v3d.resize( 3 );
for( int i = 0; i < xSize; ++i )
v3d[ i ].resize( ySize );
for( int i = 0; i < xSize; ++i )
for( int j = 0; j < ySize; ++j )
v3d[ i ][ j ].resize( zSize );