2D Matrix allocation on heap in c++

梦想的初衷 提交于 2019-12-22 06:59:11

问题


I am looking for a way to allocate a 2D (m x n) matrix on the heap where the elements are consecutive in memory. Currently I know of two ways to accomplish that:

First approach

int* M = new int[m * n];
  • Pro: The size of M can by dynamically determined.
  • Con: Indexing of M is a bit of a pain. (M[i * m + j])

Second approach

typedef int dim[2];
dim* M = new dim[n];
  • Pro: Indexing of M is just how I want it to be.
  • Con: The size of the first dimension (m) cannot be set dynamically.

Question

Is there a way to allocate a 2D matrix dynamically on the heap where I can index the elements with [i][j] and the memory allocation is consecutive?

I know it would make a lot of sense to use a class for that, but I am specifically looking for a way as described above.


回答1:


You can try this

int** M = new int*[m];
int *M_data = new int[m*n];

for(int i=0; i< m; ++i) 
{
    M[i] = M_data + i * n;
}



回答2:


Here is a minimal version of the IntArray2D class I mentioned in my comment:

class IntArray2D
{
    std::vector<int> data_;
    int height_;
    int width_;

public:

    IntArray2D(int height, int width)
    : data_(height * width), height_(height), width_(width) 
    {
    }

    int* operator[](int index)
    {
        return &data_[index * width_];
    }

    const int* operator[](int index) const
    {
        return &data_[index * width_];
    }
};

Example usage:

IntArray2D test(100, 10);
test[99][9] = 42;
int i = test[0][0];

You may want to add bounds checking, and to do that in both dimensions, you need to return an appropriate proxy object instead of a pointer. Exercise left to the reader ;-)




回答3:


NOTE: see the edit below for ways to do it. I will keep the original post as is.

Original post

To make both sizes dynamic AND the elements consecutive, you have no other way than your first method. (note: see the edit, there are ways to do it, but with g++)

Think of it this way: When you tell the compiler to compute array[i][j], it would automatically translate it to either:

*(array+i*m+j)

if the array is static and m (the number of columns) is known. Or if the array is 2D (of type type **):

*(*(array+i)+j)

The second case is how you would do it normally with 2D arrays, but the data are NOT consecutive. That leaves you with the first option. Now in the first option, at compile time, the compiler has to know m. If you want m to be set at runtime, the compiler just can't compute i*m+j.

Now there are ways to work around this. One is the use of classes as you mentioned, which wraps around the array = new type[n*m]; and overloads the [] operator properly. Another way to do it, which would require more memory (and thus I personally don't recommend) is to take a second array of type type ** and instead of setting each element to a new type[m], you set it to the beginning of rows in your one dimensional array.

Nonetheless, bottom line is, somewhere you have to have new type[n*m]

Edit: methods to do it, using g++

This emerged from the comments below:

type *array_helper = new type[n*m];
type (*array)[m] = (type (*)[m])array_helper;

Then you can use array and the elements are consecutive.

I also tried this, and it worked

type array[n][m];

and I printed the addresses, specifically checked array[i][m-1] and array[i+1][0] and the addresses are consecutive.




回答4:


You want a pointer-to-(int-array):

 cin >> w >> h;
 int (*data)[w] = (int (*)[w])new int[w*h];
 for(int y=0;y<h;y++)
 for(int x=0;x<w;x++)
     data[y][x] = (w*y)+x;



回答5:


Building off crazyjul's answer you can do it with just one memory allocation.

int **arr = new int*[col*(row+1)];
for(int a=0; c<col; ++a){
    arr[a] = (int*)&arr[(a+1)*row];
}



回答6:


C-like pseudocode:

int** M = new int*[m];
for(int i in 0..m-1) {
    M[i] = new int[n];
}



回答7:


Use boost array, matrix or STL vector?

One more thing for your matrix: Why shouldn't my Matrix class's interface look like an array-of-array?



来源:https://stackoverflow.com/questions/7684712/2d-matrix-allocation-on-heap-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!