C++ 如何动态分配矩阵?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1403150/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:52:01  来源:igfitidea点击:

How do you dynamically allocate a matrix?

c++arraysmatrixdynamic-data

提问by chustar

How do you dynamically allocate a 2D matrix in C++? I have tried based on what I already know:

你如何在 C++ 中动态分配一个二维矩阵?我已经根据我已经知道的内容进行了尝试:

#include <iostream>

int main(){
    int rows;
    int cols;
    int * arr;
    arr = new int[rows][cols];
 }

It works for one parameter, but now for two. What should I do?

它适用于一个参数,但现在适用于两个。我该怎么办?

回答by pyon

A matrix is actually an array of arrays.

矩阵实际上是数组的数组。

int rows = ..., cols = ...;
int** matrix = new int*[rows];
for (int i = 0; i < rows; ++i)
    matrix[i] = new int[cols];

Of course, to delete the matrix, you should do the following:

当然,要删除矩阵,您应该执行以下操作:

for (int i = 0; i < rows; ++i)
    delete [] matrix[i];
delete [] matrix;


I have just figured out another possibility:

我刚刚想出了另一种可能性:

int rows = ..., cols = ...;
int** matrix = new int*[rows];
if (rows)
{
    matrix[0] = new int[rows * cols];
    for (int i = 1; i < rows; ++i)
        matrix[i] = matrix[0] + i * cols;
}

Freeing this array is easier:

释放这个数组更容易:

if (rows) delete [] matrix[0];
delete [] matrix;

This solution has the advantage of allocating a single big block of memory for all the elements, instead of several little chunks. The first solution I posted is a better example of the arrays of arraysconcept, though.

这种解决方案的优点是为所有元素分配一个大内存块,而不是几个小块。不过,我发布的第一个解决方案是数组概念数组的更好示例。

回答by aJ.

You can also use std::vectorsfor achieving this:

您还可以使用std::vectors来实现这一点:

using std::vector< std::vector<int> >

使用 std::vector< std::vector<int> >

Example:

例子:

std::vector< std::vector<int> > a;

  //m * n is the size of the matrix

    int m = 2, n = 4;
    //Grow rows by m
    a.resize(m);
    for(int i = 0 ; i < m ; ++i)
    {
        //Grow Columns by n
        a[i].resize(n);
    }
    //Now you have matrix m*n with default values

    //you can use the Matrix, now
    a[1][0]=1;
    a[1][1]=2;
    a[1][2]=3;
    a[1][3]=4;

//OR
for(i = 0 ; i < m ; ++i)
{
    for(int j = 0 ; j < n ; ++j)
    {      //modify matrix
        int x = a[i][j];
    }

}

回答by yoco

Try boost::multi_array

试试boost::multi_array

#include <boost/multi_array.hpp>

int main(){
    int rows;
    int cols;
    boost::multi_array<int, 2> arr(boost::extents[rows][cols] ;
}

回答by maykeye

arr = new int[cols*rows];

If you either don't mind syntax

如果你不介意语法

arr[row * cols + col] = Aij;

or use operator[] overaloading somewhere. This may be more cache-friendly than array of arrays, or may be not, more probably you shouldn't care about it. I just want to point out that a) array of arrays is not only solution, b) some operations are more easier to implement if matrix located in one block of memory. E.g.

或在某处使用 operator[] 重载。这可能比数组数组对缓存更友好,或者可能不是,更可能你不应该关心它。我只想指出 a) 数组数组不仅是解决方案,b) 如果矩阵位于一个内存块中,则某些操作更容易实现。例如

for(int i=0;i < rows*cols;++i)
   matrix[i]=someOtherMatrix[i];

one line shorter than

一行短于

for(int r=0;i < rows;++r)
  for(int c=0;i < cols;++s)
     matrix[r][c]=someOtherMatrix[r][c];

though adding rows to such matrix is more painful

虽然向这样的矩阵添加行更痛苦

回答by adatapost

 #include <iostream>

    int main(){
        int rows=4;
        int cols=4;
        int **arr;

        arr = new int*[rows];
        for(int i=0;i<rows;i++){
           arr[i]=new int[cols];
        }
        // statements

        for(int i=0;i<rows;i++){
           delete []arr[i];
        }
        delete []arr;
        return 0;
     }

回答by DmitryK

or you can just allocate a 1D array but reference elements in a 2D fashion:

或者您可以只分配一维数组但以二维方式引用元素:

to address row 2, column 3 (top left corner is row 0, column 0):

解决第 2 行第 3 列(左上角为第 0 行第 0 列):

arr[2 * MATRIX_WIDTH + 3]

arr[2 * MATRIX_WIDTH + 3]

where MATRIX_WIDTH is the number of elements in a row.

其中 MATRIX_WIDTH 是一行中的元素数。

回答by sballot

const int nRows = 20;
const int nCols = 10;
int (*name)[nCols] = new int[nRows][nCols];
std::memset(name, 0, sizeof(int) * nRows * nCols); //row major contiguous memory
name[0][0] = 1; //first element
name[nRows-1][nCols-1] = 1; //last element
delete[] name;

回答by Nikos

Here is the most clear & intuitive way i know to allocate a dynamic 2d array in C++. Templated in this example covers all cases.

这是我所知道的在 C++ 中分配动态二维数组的最清晰直观的方法。此示例中的模板涵盖所有情况。

template<typename T> T** matrixAllocate(int rows, int cols, T **M)
{
    M = new T*[rows];
    for (int i = 0; i < rows; i++){
        M[i] = new T[cols];
    }
    return M;
}

... 

int main()
{
    ...
    int** M1 = matrixAllocate<int>(rows, cols, M1);
    double** M2 = matrixAllocate(rows, cols, M2);
    ...
}

回答by Martin Beckett

The other answer describing arrays of arrays are correct.
BUT if you are planning of doing a anything mathematical with the arrays - or need something special like sparse matrices you should look at one of the many maths libs like TNTbefore re-inventing too many wheels

描述数组数组的另一个答案是正确的。
但是如果你打算用数组做任何数学运算——或者需要一些特殊的东西,比如稀疏矩阵,你应该在重新发明太多轮子之前查看TNT等众多数学库之一

回答by StackedCrooked

I have this grid class that can be used as a simple matrix if you don't need any mathematical operators.

如果您不需要任何数学运算符,我有这个网格类可以用作简单的矩阵。

/**
 * Represents a grid of values.
 * Indices are zero-based.
 */
template<class T>
class GenericGrid
{
    public:
        GenericGrid(size_t numRows, size_t numColumns);

        GenericGrid(size_t numRows, size_t numColumns, const T & inInitialValue);

        const T & get(size_t row, size_t col) const;

        T & get(size_t row, size_t col);

        void set(size_t row, size_t col, const T & inT);

        size_t numRows() const;

        size_t numColumns() const;

    private:
        size_t mNumRows;
        size_t mNumColumns;
        std::vector<T> mData;
};


template<class T>
GenericGrid<T>::GenericGrid(size_t numRows, size_t numColumns):
    mNumRows(numRows),
    mNumColumns(numColumns)
{
    mData.resize(numRows*numColumns);
}


template<class T>
GenericGrid<T>::GenericGrid(size_t numRows, size_t numColumns, const T & inInitialValue):
    mNumRows(numRows),
    mNumColumns(numColumns)
{
    mData.resize(numRows*numColumns, inInitialValue);
}


template<class T>
const T & GenericGrid<T>::get(size_t rowIdx, size_t colIdx) const
{
    return mData[rowIdx*mNumColumns + colIdx];
}


template<class T>
T & GenericGrid<T>::get(size_t rowIdx, size_t colIdx)
{
    return mData[rowIdx*mNumColumns + colIdx];
}


template<class T>
void GenericGrid<T>::set(size_t rowIdx, size_t colIdx, const T & inT)
{
    mData[rowIdx*mNumColumns + colIdx] = inT;
}


template<class T>
size_t GenericGrid<T>::numRows() const
{
    return mNumRows;
}


template<class T>
size_t GenericGrid<T>::numColumns() const
{
    return mNumColumns;
}