我如何声明一个2d数组使用新?
比如,对于一个“普通”数组,我将:
int* ary = new int[Size]
but
int** ary = new int[sizeY][sizeX]
A)不工作/编译b)没有完成什么:
int ary[sizeY][sizeX]
所做的事。
我如何声明一个2d数组使用新?
比如,对于一个“普通”数组,我将:
int* ary = new int[Size]
but
int** ary = new int[sizeY][sizeX]
A)不工作/编译b)没有完成什么:
int ary[sizeY][sizeX]
所做的事。
当前回答
在c++ 11中可以:
auto array = new double[M][N];
这样,内存就不会被初始化。要初始化它,可以这样做:
auto array = new double[M][N]();
示例程序(用"g++ -std=c++11"编译):
#include <iostream>
#include <utility>
#include <type_traits>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;
int main()
{
const auto M = 2;
const auto N = 2;
// allocate (no initializatoin)
auto array = new double[M][N];
// pollute the memory
array[0][0] = 2;
array[1][0] = 3;
array[0][1] = 4;
array[1][1] = 5;
// re-allocate, probably will fetch the same memory block (not portable)
delete[] array;
array = new double[M][N];
// show that memory is not initialized
for(int r = 0; r < M; r++)
{
for(int c = 0; c < N; c++)
cout << array[r][c] << " ";
cout << endl;
}
cout << endl;
delete[] array;
// the proper way to zero-initialize the array
array = new double[M][N]();
// show the memory is initialized
for(int r = 0; r < M; r++)
{
for(int c = 0; c < N; c++)
cout << array[r][c] << " ";
cout << endl;
}
int info;
cout << abi::__cxa_demangle(typeid(array).name(),0,0,&info) << endl;
return 0;
}
输出:
2 4
3 5
0 0
0 0
double (*) [2]
其他回答
在c++ 11中可以:
auto array = new double[M][N];
这样,内存就不会被初始化。要初始化它,可以这样做:
auto array = new double[M][N]();
示例程序(用"g++ -std=c++11"编译):
#include <iostream>
#include <utility>
#include <type_traits>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;
int main()
{
const auto M = 2;
const auto N = 2;
// allocate (no initializatoin)
auto array = new double[M][N];
// pollute the memory
array[0][0] = 2;
array[1][0] = 3;
array[0][1] = 4;
array[1][1] = 5;
// re-allocate, probably will fetch the same memory block (not portable)
delete[] array;
array = new double[M][N];
// show that memory is not initialized
for(int r = 0; r < M; r++)
{
for(int c = 0; c < N; c++)
cout << array[r][c] << " ";
cout << endl;
}
cout << endl;
delete[] array;
// the proper way to zero-initialize the array
array = new double[M][N]();
// show the memory is initialized
for(int r = 0; r < M; r++)
{
for(int c = 0; c < N; c++)
cout << array[r][c] << " ";
cout << endl;
}
int info;
cout << abi::__cxa_demangle(typeid(array).name(),0,0,&info) << endl;
return 0;
}
输出:
2 4
3 5
0 0
0 0
double (*) [2]
为什么不使用STL:vector?很简单,你不需要删除向量。
int rows = 100;
int cols = 200;
vector< vector<int> > f(rows, vector<int>(cols));
f[rows - 1][cols - 1] = 0; // use it like arrays
你也可以初始化“数组”,只是给它一个默认值
const int DEFAULT = 1234;
vector< vector<int> > f(rows, vector<int>(cols, DEFAULT));
来源:如何在C/ c++中创建2,3(或多)维数组?
从静态数组的例子中,我假设你想要一个矩形数组,而不是锯齿形数组。你可以使用以下方法:
int *ary = new int[sizeX * sizeY];
然后你可以像这样访问元素:
ary[y*sizeX + x]
不要忘记在ary上使用delete[]。
试着这样做:
int **ary = new int* [sizeY];
for (int i = 0; i < sizeY; i++)
ary[i] = new int[sizeX];
这个答案的目的不是添加其他答案没有涵盖的新内容,而是扩展@Kevin Loney的答案。
你可以使用轻量级声明:
int *ary = new int[SizeX*SizeY]
访问语法将是:
ary[i*SizeY+j] // ary[i][j]
但这对大多数人来说都很麻烦,可能会导致混乱。所以,你可以这样定义宏:
#define ary(i, j) ary[(i)*SizeY + (j)]
现在可以使用非常相似的语法ary(i, j) //表示ary[i][j]。 这具有简单美观的优点,同时,使用表达式代替索引也更简单,不那么令人困惑。
要访问,比如说,ary[2+5][3+8],你可以写ary(2+ 5,3 +8),而不是看起来复杂的ary[(2+5)*SizeY +(3+8)],也就是说,它节省了括号,有助于可读性。
警告:
尽管语法非常相似,但并不相同。 如果将数组传递给其他函数,则必须以相同的名称传递SizeY(或者声明为全局变量)。
或者,如果你需要在多个函数中使用数组,那么你可以在宏定义中添加SizeY作为另一个参数,如下所示:
#define ary(i, j, SizeY) ary[(i)*(SizeY)+(j)]
你懂的。当然,这会变得太长而没有用处,但它仍然可以防止+和*的混淆。
当然不推荐这样做,大多数有经验的用户会谴责这是一种糟糕的做法,但我还是忍不住要分享它,因为它很优雅。
编辑: 如果你想要一个适用于任意数量数组的可移植解决方案,你可以使用以下语法:
#define access(ar, i, j, SizeY) ar[(i)*(SizeY)+(j)]
然后你可以使用访问语法将任意大小的数组传递给调用:
access(ary, i, j, SizeY) // ary[i][j]
附注:我已经测试了这些,在g++14和g++11编译器上可以使用相同的语法(作为左值和右值)。