How to declare a 2d array in C++ using new (转载)
原文链接:http://stackoverflow.com/questions/936687/how-do-i-declare-a-2d-array-in-c-using-new
-------------------------------------------------------------------
How do i declare a 2d array using new?
Like, for a "normal" array I would:
int* ary = new int[Size]
but
int** ary = new int[sizeY][sizeX]
a) doesn't work/compile and b) doesn't accomplish what:
int ary[sizeY][sizeX]
does.
-------------------------------------------------------------------
A dynamic 2D array is basically an array of pointers to arrays. You should initialize it using a loop:
int** ary = new int*[sizeX];
for(int i = 0; i < sizeX; ++i)
ary[i] = new int[sizeY];
The above, for sizeX = 4 and sizeY = 5, would produce the following:

-------------------------------------------------------------------
int** ary = new int[sizeY][sizeX]
should be:
int **ary = new int*[sizeY];
for(int i = 0; i < sizeY; ++i) {
ary[i] = new int[sizeX];
}
and then clean up would be:
for(int i = 0; i < sizeY; ++i) {
delete [] ary[i];
}
delete [] ary;
EDIT: as Dietrich Epp pointed out in the comments this is not exactly a light weight solution. An alternative approach would be to use one large block of memory:
int *ary = new int[sizeX*sizeY];
// ary[i][j] is then rewritten as
ary[i*sizeY+j]
-------------------------------------------------------------------
Don't.
Unless you have good reason, use std::vector<std::vector<int> > instead. Memory management will be far less error prone.
Edit:
If you start to run into issues with the memory being non-contiguous, such as pointed out in the comments by Dietrich Epp, you could switch to using std::vector<int> and allocate (rows * columns) elements.
You can then get a hold of the first element of this vector (&v[0]) and use the techniques in the other answers to treat it as a normal int[][].
However I would only do this if you actually profiled your code and saw that the non-contiguous memory was causing performance problems. It would likely only be an issue if you had a very large 2-D array. At least that is my guess. Again, profiling is the only real way to know.
The main point of my answer was to let vector do the memory management for you.
-------------------------------------------------------------------
In C++11 it is possible:
auto array = new double[M][N];
This way, the memory is not initialized. To initialize it do this instead:
auto array = new double[M][N]();
Sample program (compile with "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 propoer way to zero-initilize 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