Two-dimensional matrix distribution on the heap in C ++

I am looking for a way to allocate a 2D matrix (mxn) in a heap, where the elements are consecutive in memory. I currently know two ways to achieve this:

First approach

int* M = new int[m * n]; 
  • Pro: Size M can be determined dynamically.
  • Con: Indexing M little painful. ( M[i * m + j] )

Second approach

 typedef int dim[2]; dim* M = new dim[n]; 
  • Pro: indexing M is exactly what I want.
  • Con: size of the first dimension (m) cannot be set dynamically.

Question

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

I know that it would be very useful to use a class for this, but I am specifically looking for a method as described above.

+4
source share
7 answers

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; } 
+3
source

Below is the minimum version of the IntArray2D class 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_]; } }; 

Usage example:

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

You can add border checking and do it in both dimensions, you need to return the corresponding proxy object instead of the pointer. Reader exercise; -)

+3
source

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

Original post

To make both sizes dynamic and sequential elements, you have no other way than your first method . ( note : see editing, there are ways to do this, but with g ++)

Think of it this way: when you tell the compiler to compute the array [i] [j], it will automatically translate it into:

 *(array+i*m+j) 

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

 *(*(array+i)+j) 

The second case is as you usually do with 2D arrays, but the data is NOT sequential. This leaves you with the first option. Now, in the first version, at compile time, you should know m . If you want m be set at runtime, the compiler simply cannot compute i*m+j .

Now there are ways around this. One of them is the use of classes, as you mentioned, that wrap around array = new type[n*m]; and correctly overload the operator [] . Another way to do this, which will require more memory (and therefore I personally do not recommend it), is to take a second array of type type ** and instead of setting each element to new type[m] , you set it to the beginning lines in your one-dimensional array.

However, the bottom line somewhere you should have new type[n*m]

Edit: methods for this using g ++

This came from the comments below:

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

Then you can use an array and the elements are sequential.

I tried this too and it worked

 type array[n][m]; 

and I printed the addresses, in particular, the marked array[i][m-1] and array[i+1][0] , and the addresses are sequential.

+2
source

You need a pointer to-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; 
+1
source

By creating an answer to crazyjul, you can do this with only one memory allocation.

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

C-like pseudo-code:

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

All Articles