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:

enter image description here

-------------------------------------------------------------------

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] << " ";
        cout << endl;
    }

    int info;
    cout << abi::__cxa_demangle(typeid(array).name(),0,0,&info) << endl;

    return 0;
}

Output:

2 4 
3 5 

0 0 
0 0 
double (*) [2]
-------------------------------------------------------------------
I presume from your static array example that you want a rectangular array, and not a jagged one. You can use the following:
int *ary = new int[sizeX * sizeY];

Then you can access elements as:

ary[y*sizeX + x]

Don't forget to use delete[] on ary.

 
posted @ 2014-10-18 23:02  Learn Open CAD  阅读(162)  评论(0)    收藏  举报