我已经知道如何使用new
创建动态2D矩阵并使用delete
释放它。由于C ++ 11具有许多新的内存功能,例如unique_ptr
,array
容器等;什么是创建2D矩阵的好方法,以便不需要使用delete
运算符明确释放矩阵?
答案 0 :(得分:3)
最简单的方法之一是使用矢量矢量
const int N = 10;
const int M = 10;
vector<vector<int>> matrix2d(N, vector<int>(M, 0)); // 10x10 zero-initialized matrix
matrix2d[0][0] = 42;
您当然可以使用单个向量并将其包装到存取器类
中vector<int> matrix(N * M, 0) // Ditto as above, but needs stride-aware accessors
为了完整起见,我会在这里发布一个小例子
template <typename T>
class Matrix2D {
std::vector<T> data;
unsigned int sizeX, sizeY;
public:
Matrix2D (unsigned int x, unsigned int y)
: sizeX (x), sizeY (y) {
data.resize (sizeX*sizeY);
}
T& operator()(unsigned int x, unsigned int y) {
if (x >= sizeX || y>= sizeY)
throw std::out_of_range("OOB access"); // Throw something more appropriate
return data[sizeX*y + x]; // Stride-aware access
}
};
或者可能将您的方式与smart pointer结合起来。请注意,vector<vector<int>>
方法应谨慎使用,因为向量彼此独立,并且没有任何内容可以强制它们应该保持其大小固定。
答案 1 :(得分:3)
我强烈建议您使用array_view
中的GSL,这最终将成为标准的一部分。
#include <array>
#include <vector>
#include "array_view.h" // must be manually imported until standardization
int main()
{
std::array<int, 10> arr{}; // 10 ints on the stack
std::vector<int> vec{12}; // 12 ints on the heap
auto a = gsl::array_view<int, 2>{{2, 5}, arr}; // 2D, 2x5 matrix
auto b = gsl::array_view<int, 3>{{3, 2, 2}, vec}; // 3D, 3x2x2 matrix
auto c = gsl::array_view<int>{vec}; // 1D, spans from `begin()` to `end()`
a[{0,3}] += b[{0,1,1}] * -c[2]; // access syntax
}
N.B。 array_view
在其查看范围的生命周期内持有无控件。有关详细信息,请参阅here。
array_view已经死了,因为它在处理具有零成本抽象的多维数组时变得过于复杂。您应该使用span中的GSL。
有关span的更多信息,请参阅this。
答案 2 :(得分:0)
基于以上答案,我发现了一种创建矩阵的简单方法,尽管不使用C ++ 11特性。这是一个例子。
#include <iostream>
#include <vector>
using namespace std;
typedef vector<vector<int>> Matrix2D;
typedef vector<Matrix2D> Matrix3D;
Matrix2D my_arr;
int main()
{
const size_t N = 9;
for(unsigned s = 4; s <= N; s++)
{
my_arr.resize(s);
for(unsigned i = 0; i < s; i++)
my_arr[i].resize(s,s);
for(unsigned i = 0; i < s; i++)
{
for(unsigned j = 0; j < s; j++)
cout << my_arr[i][j] << " ";
cout << endl;
}
cout << "\n\n";
}
return 0;
}