如何使用 'new' 而不是 'malloc' 来动态分配二维数组?

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

我想用二维指针制作矩阵。

当我使用'malloc'和'free'函数进行内存使用时没有问题(见我的代码)。 但是,我无法使用 'new' 和 'delete'.

编写相同的代码

如你所知,一维指针可以用'new'声明。例如,

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

那么,如何使用'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);

嗯,直接等价的是这样的:

// 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;

不过,你真的不想要这个。这是一团糟,没有内存位置。

更不用说手动内存管理完全容易出错,事实证明您在原始代码中有 row double 的泄漏。

这有什么问题:

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;
};

它使用 vector 来避免 any 那种讨厌的内存管理,并将 2D 索引访问包装在实际上是单个数据缓冲区的周围,这样您就没有n 指针间接寻址。

您可以根据需要将布局调整为行优先或列优先。

分配,

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

要取消分配,

for(size_t i = 0 ; i < row ; ++i)
    delete matrix[i];
delete[] matrix;

我的方法与其他解决方案略有不同。该函数有 3 个参数,3D 指针(double 由指针指向,指针指向指针,指针指向指针 x),大小rowscolumnssize_t(索引的有符号值是开销)。它只允许通过间接引用函数来使用在 main() 中定义的 2D 指针变量。 En passant,这将通过使用 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

您不必单独分配列。一大块就够了,也方便删除。

分配:

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

免费:

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