1

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);
1

4 Answers 4

5

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 doubles 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.

1
  • 1
    Why also not adding a double *operator[](const unsigned int y){return data.data()+y*row;}, to simulate indexing :)
    – Cristik
    Commented May 26, 2015 at 16:54
1

You don't have to allocate the columns individually. One big block is sufficient, which also makes it easier to delete.

To allocate:

double** matrix = new double* row;
double*  ptr = new double [row * column];
for ( int i = 0; i < row; i++, ptr += column )
    matrix[i] = ptr;

To free:

delete [] matrix[0];
delete [] matrix;
0

To allocate,

double** matrix = new double*[row];
for(size_t i = 0 ; i < row ; ++i)
    matrix[i] = new double[column];

To de-allocate,

for(size_t i = 0 ; i < row ; ++i)
    delete matrix[i];
delete[] matrix;
1
  • AH! Didn't exec. My bad. Edited. Commented May 26, 2015 at 17:22
0

I have slightly different approach rather than the other solutions. The function takes 3 parameters, 3D pointer(double which pointed to by a pointer which is pointed to a pointer which is pointed to a pointer x), sizes of rows and columns which are size_t (signed values for indices are overhead). It just allows to use the 2D pointer variable being defined in main() through passing by indirect reference to function. En passant, it would be accomplished with using double**& x.

#include <iostream>

size_t const SIZE { 2 };

void Alloc2D(double ***x, size_t row, size_t col);
void Alloc2D(double ***x, size_t row, size_t col)
{ 
    *x = new double*[row];
    for(size_t i {}; i < row; i++)
    {
        (*x)[i] = new double[col];
    }
}

int main()
{
    double** matrix;

    // 2 x 2 matrix
    Alloc2D(&matrix, SIZE, SIZE);
    matrix[0][0] = 9;
    matrix[0][1] = 8;
    matrix[1][0] = 7;
    matrix[1][1] = 6;


    for(size_t i {}; i < SIZE; i++)
        delete matrix[i];
    delete[] matrix;
}

Run on IDE

Not the answer you're looking for? Browse other questions tagged or ask your own question.