Superlunary - 7 months ago 33
C++ Question

# How to use 'new' instead of 'malloc' to allocate a 2D-array, dynamically?

I'd like to make matrix using 2-D pointer.

There was no problem when I used 'malloc' and 'free' functions for memory use (see my code).
However, I couldn't write the same code using 'new' and 'delete'.

As you know, 1-D pointer can be declared by 'new'. For example,

``````double *example = new double [10];
delete [] example;
``````

Then, how can I declare 2-D pointer using 'new'?

``````    double **matrix;    // 2-D pointer which represents entries of a matrix
int row, column;    // the number of rows and column of the matrix
int i;

// set the size of the matrix
row = 3;
column = 5;

// allocate memories related to the number of rows
matrix = (double **)malloc(sizeof(double *) * row);

// allocate memories related to the number of columns of each row
for(i = 0; i < row; i++)
{
matrix[i] = (double (*))malloc(sizeof(double) * column);
}

// example: use of matrix
matrix[2][4] = 10.5;

// return used memories
free(matrix);
``````

Well, the direct equivalent is like this:

``````// allocate memories related to the number of rows
double** matrix = new double*[row];

// allocate memories related to the number of columns of each row
for(i = 0; i < row; i++)
{
matrix[i] = new double[column];
}

// usage here

// de-allocate memories related to the number of columns of each row
// (YOU FORGOT THIS IN YOUR ORIGINAL CODE!!!)
for(i = 0; i < row; i++)
{
delete matrix[i];
}

delete[] matrix;
``````

Really, though, you don't want this. It's a complete mess and has like no memory locality.

Not to mention all that manual memory management is totally error-prone, as evidenced by the fact that you have a leak of `row` `double`s in your original code.

What's wrong with this:

``````struct Matrix
{
Matrix(const unsigned int row, const unsigned int column)
: row(row)
, column(column)
, data(row*column, 0)
{}

double& at(const unsigned int y, const unsigned int x)
{
return data[y + x*row];
}

private:
const unsigned int row, column;
std::vector<double> data;
};
``````

It uses `vector` to avoid any of that nasty memory management, and wraps 2D index access around what's actually a single data buffer so that you don't have n pointer indirections.

You can adjust the layout to be row-major or column-major depending on your needs.