### Need Help There are some problem going on in the definition of allocateData2DbyMalloc() function which block the memory allocation of a 2D array. Can anyone help me please?

 ``1234567891011121314151617181920212223242526272829303132`` `````` #include #include #include #include using namespace std; template type1 allocateData2DbyMalloc(type1 data2D, type2 nRow, type2 nColumn) { int size = 0; data2D = (type1)malloc(nRow * sizeof(typeid(**data2D).name())); for (int row = 0; row < nRow; row++) data2D[row] = (typeid(*data2D).name())malloc(nColumn * sizeof(typeid(**data2D).name())); return data2D; } int main() { int n = 4; double** constrainVector; constrainVector = nullptr; constrainVector = allocateData2DbyMalloc(constrainVector, n, n); for(int i = 0; i < n; i++) for (int j = 0; j < n; j++) constrainVector[i][j] = 6.0; return 0; } `````` Why on earth are you using malloc?

Anyway, if constrainVector is a double**, to allocate the array of rows of a dynamic 2D array, you'd need to do `malloc(sizeof(*data2D) * num_rows);`

And then for each inner array, you'd have to do `malloc(sizeof(**data2D) * num_columns);`
Last edited on Hi Ganado, thanks for the question. I am using malloc() because at every time step I need to reallocate the memory based on the number of row and column. By the way, malloc(sizeof(*data2D) * num_rows) will return the void pointer, right?. And the I need to cast as type1. That's not a valid reason to use malloc, in my opinion.

I'm going to skip the usual "use std::vector" lecture and just say:
malloc/free is C
new/delete is C++

So if you must use raw memory management, use new/delete, not malloc/free.
 ``12345678910111213141516171819202122232425262728293031323334353637383940414243444546`` ``````#include int main() { int rows = 4; int columns = 7; // // Dynamic allocation // double** constrainVector = new double*[rows]{}; for (int i = 0; i < columns; i++) { constrainVector[i] = new double[columns]{}; } // // just filling with numbers to differentiate them // for(int i = 0; i < rows; i++) for (int j = 0; j < columns; j++) constrainVector[i][j] = (i+1) * (j+1) % 10; // // Display // for(int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { std::cout << constrainVector[i][j] << " "; } std::cout << '\n'; } // // Clean-up // for (int i = 0; i < columns; i++) { delete[] constrainVector[i]; } delete[] constrainVector; return 0; }``````

 By the way, malloc(sizeof(*data2D) * num_rows) will return the void pointer, right?. And the I need to cast as type1.
In C, no casting in needed. (And C purists will protest the unnecessary cast)
In C++, yes you need to cast.
Last edited on Now, the "use std::vector" lecture.

std::vector lets you resize an array, and takes care of all the dynamic allocation/destruction for you.
No memory leaks possible!

 ``12345678910111213141516171819202122232425262728293031323334353637383940`` ``````#include #include int main() { int rows = 4; int columns = 7; // // Dynamic allocation // std::vector > constrainVector( rows, std::vector(columns) ); // // just filling with numbers to differentiate them // for(int i = 0; i < rows; i++) for (int j = 0; j < columns; j++) constrainVector[i][j] = (i+1) * (j+1) % 10; // // Display // for(int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { std::cout << constrainVector[i][j] << " "; } std::cout << '\n'; } // // No clean-up needed. Great! // return 0; }``````
Last edited on Thanks a lot bro. Very nice of you. Thanks again. > There are some problem going on
I see

> I am using malloc() because at every time step I need to reallocate
I'm drinking wax so the nails and bolts don't hurt my stomach

> `typeid(*data2D).name()`
you wrote `type1 data2D`, `type1' is the type
by the way, you don't seem to use that parameter
you could have written `type1 **data2D` and then use `type1*' for the cast

if you want one contiguous block
 ``12345678`` `````` double** constrainVector = new double*[rows]; constrainVector = new double[rows*columns]{}; for (int i = 1; i < rows; i++) constrainVector[i] = constrainVector+i*columns; //clean up delete[] constrainVector; delete[] constrainVector;``````
Last edited on That's pretty clever, it lets you address it with vec[i][j] while still keeping it contiguous. I've always just done `my_vec[width * y + x];`
I might start using that in my code.
Edit: Err... wait. I can't use that trick with vector without a wrapper class. Ah well, still cool.
Last edited on there is a way to morph a block to look 2-d without the loop. hang on, Ill look it up.

I think this is one way, hopefully I did this right... and hopefully 'rows' isnt actually columns, Im having concentration issue today.

 ``1234567891011121314151617`` ``````int main() { int * i = new int; for(int x = 0; x < 100; x++) i[x] = x; typedef int rows; //making a 10x10 here rows* rp = (rows*)(i); cout << rp << endl; //3rd row, 4th colum... 34 (3*10+4)! typedef int rows2; //making a 5x20 here rows2* rp2 = (rows2*)(i); cout << rp2; //3rd row, 4th colum... 19 (3*5+4) } ``````

I think you can do the above without the typedefs, using some other pointer & casting magic. The idea is the same, whatever syntax you need to get there

for any beginners, what this does conceptually is make a 1-d array of 1-d arrays, giving a 2-d array. More precisely, deep inside, you create a type that is N units wide, and take a pointer to that. C++'s strongly typed pointers allocate that width for you, so when you cast the big block to a pointer of the wide small type, it slices it for you, moving a full row at a time when you add 1 to that index, because +1 is N units wide.

these tricks can give you some really bad bugs if you mess it up. It yields high performance at high risk.
Last edited on