如何删除动态创建的矩阵?这可能是重复的,我为此道歉,但到目前为止我真的找不到明确的答案。我按如下方式初始化矩阵:
float ** createMatrix(unsigned int Nrows, unsigned int Ncols) {
float ** result = NULL;
if (Nrows != 0 && Ncols != 0) {
// create the matrix on the heap
result = new float * [Nrows];
result[0] = new float [Nrows*Ncols]();
// link the rows
for (int i = 1; i < Nrows; i++) {
result[i] = result[i-1] + Ncols;
}
}
现在,我想创建一个删除它的函数。我需要两个单独的语句来删除M [0]和M,还是只需要一个M?即我需要:
void deleteMatrix(float **M){
delete[] M[0];
delete[] M;
}
或简单:
void deleteMatrix(float **M){
delete[] M;
}
任何帮助/解释都会受到大力赞赏。当deleteMatrix(M)运行时,两个版本都“工作”并且在控制台中没有显示任何错误,所以我很困惑。谢谢!
答案 0 :(得分:1)
这些&#34; 2D阵列&#34;问题不断出现。我想我会回答一个。
不要使用数组[]。请勿使用new[]
和delete[]
。只是不要。使用std::vector<std::vector<int>>
让C ++的奇迹为你做所有新的和删除。或者对于严肃的事情,使用设计良好的开源库,如boost::matrix. C ++是很酷的。
以下是入门套件。它可以通过多种方式得到改善,私有化和抽象化。
#include <vector>
using std::size_t;
template<class T>
struct Matrix {
using matrix_type = std::vector<std::vector<T>>;
matrix_type matrix;
Matrix(size_t rows, size_t cols)
: matrix(rows, matrix_type::value_type(cols))
{}
};
int main() {
size_t Nrows = 5u;
size_t Ncols = 2u;
Matrix<int> mx(Nrows, Ncols);
auto& matrix = mx.matrix; // Now use matrix[i][j] or whatever.
// Here you can do anything with matrix that your could do with
// an array or arrays ... and more. And it cleans up after iself.
}
答案 1 :(得分:1)
正如许多其他人在每次使用new[]
时所说的那样,您必须拥有匹配的[] delete
。但是,由于它目前支持您的功能以及如何声明/定义它们,我相信您遇到了X/Y
问题。
这就是为什么!
你建议你这样声明你的删除功能:你还说这两个版本都有效,并且没有显示任何错误......在你发布的问题中,两个版本完全一样......
void deleteMatrix( float** M ) {
// delete[] rows
// delete[] cols
}
我在这里看到的问题是,当你传入指向浮点指针的指针时,该函数不知道矩阵的维数。它可以是2x2
,2x3
,3x2
,3x3
,MxN
等。如果不知道矩阵的维度,你怎么能写出for循环遍历内部或嵌套数组?您必须将这些维度传递给删除功能:
void deleteMatrix( float** M, int rowSize, int colSize ) {
for ( int row = 0; row < rowSize; row++ ) {
delete [] M[i];
}
delete [] M;
}
以下示例与您尝试实施的内容类似:thispointer.com
在你的实际问题之外;这往往更像是C方法或过时的C ++方法。不建议使用原始指针和新的&amp;自由删除。使用智能指针更好。但是对于像矩阵类这样的构造,有很多可以自由使用的库已经定义了这样的类 - 使用的接口和一些最流行的类:
修改 - 用户PaulMcKenzie清除了一个我早已忘记的有效点,因为我主要使用vector<object>
或vector<shared_ptr<object>>
。自从我第一次学习指针 - 多维数组并且我已经忘记了关于连续数组的概念以来已经超过15年了。他在评论部分发给我的问题的答案清楚地解释了我忘记了什么;找到here。如果数组在内存中不连续,那么是的X/Y
问题不知道它们的维度,但是因为它们是;不需要知道尺寸。而你已经提出的建议应该有效:
void deleteMatrix(float **M){ delete[] M[0]; delete[] M; }
编辑 - 我正在浏览我的库中的一些类,这里是一个模板矩阵类,我用任何维度矩阵MxNx...ith
编写它它的易用性和使用非常灵活。如果您愿意,可以对其进行扩展:我没有进行任何type
检查或assertions
,但可以轻松添加。
使用它就像:
#include <iostream>
#include "Matrix.h"
int main() {
Matrix<int, 2, 2> imat3x3( 1, 2, 3, 4, 5, 6, 7, 8, 9 );
// calling elements() and using vector's [] operator
for ( int i = 0; i < 9; i++ )
std::cout << imat3x3.elements()[i] << ' ';
std::cout << '\n';
// Using class's [] operator
for ( int i = 0; i < 9; i++ )
std::cout << imat3x3[i] << ' ';
std::cout << '\n';
// Using class's () operator
for ( int i = 0; i < 9; i++ )
std::cout << imat3x3(i) << ' ';
std::cout << '\n';
// Okay that was a 3x3 matrix of ints, lets do a 2x2x2 matrix of floats
Matrix<float,2,2,2> fmat2x2x2( 0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f );
// now the operators
for ( int i = 0; i < 8; i++ ) {
std::cout << fmat2x2x2[i] << "f ";
std::cout << '\n';
for ( int i = 0; i < 8; i++ ) {
std::cout << fmat2x2x2(i) << "f ";
std::cout << '\n';
std::cout << "\nPress any key and enter to quit.\n";
std::cin.get();
return 0;
}
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <vector>
#include <algorithm>
#include <numeric>
template<typename Type, size_t... Dims>
class Matrix {
public:
static const size_t _numDims = sizeof...(Dims);
private:
size_t _numElements;
std::vector<Type> _elements;
std::vector<size_t> _strides;
public:
Matrix() noexcept;
template<typename... Args>
Matrix( Args&&... args ) noexcept;
const Type& operator[]( size_t idx );
const Type operator[]( size_t idx ) const;
const Type& operator() ( size_t idx );
const Type operator() ( size_t idx ) const;
size_t numElements() const {
return _elements.size();
}
const std::vector<size_t>& strides() const {
return _strides;
}
const std::vector<Type>& elements() const {
return _elements;
}
};
#include "Matrix.inl"
#endif // !MATRIX_H
Matrix.inl
template<typename Type, size_t... Dims>
Matrix<Type, Dims...>::Matrix() noexcept :
_strides( { Dims... } ) {
using std::begin;
using std::end;
auto mult = std::accumulate( begin( _strides ), end( strides ), 1, std::multiplies<>() );
_numElements = mult;
_elements.resize( _numElements );
}
template<typename Type, size_t... Dims>
template<typename... Args>
Matrix<Type, Dims...>::Matrix( Args&&... args ) noexcept :
_elements( { args... } ),
_strides( { Dims... } ) {
_numElements = _elements.size();
}
template<typename Type, size_t... Dims>
const Type Matrix<Type, Dims...>::operator[]( size_t idx ) const {
return _elements[idx];
}
template<typename Type, size_t... Dims>
const Type& Matrix<Type, Dims...>::operator[]( size_t idx ) {
return _elements[idx];
}
template<typename Type, size_t... Dims>
const Type Matrix<Type, Dims...>::operator()( size_t idx ) const {
return _elements[idx];
}
template<typename Type, size_t... Dims>
const Type& Matrix<Type, Dims...>::operator()( size_t idx ) {
return _elements[idx];
}
Matrix.cpp
- 这个cpp文件不是必需的我只需要在调试类的基本编译器错误时轻松编译它
#include "Matrix.h"
我没有证明使用numElements()
或stride()
函数,但它们应该是相当自我解释的。 strides函数是一个非常好的功能,因为如果用户调用模板<type, 1,3,5>
给你一个1x3x5
矩阵;这些存储在_strides
成员向量中。这样,您始终可以获得每个维度大小所需的索引。
现在,如果你想要你的矩阵在堆上;而不是尝试执行double pointer
或[][]
并将每个元素放在堆上,使用此类有两个选项。
您可以直接将实例化对象放在堆上,也可以让此类同时保存堆对象。
std::shared_ptr<Matrix<int,2,2>> ptrMat2x2; // A heap pointer of the matrix
Matrix<shared_ptr<int>,3,3> mat3x3ptrs; // A matrix of heap objects.
乍一看代码看起来有点奇怪,但这表明两种情况都可以完成:
#include <iostream>
#include "Matrix.h"
int main() {
// A Matrix<> on the heap via shared_ptr`
std::shared_ptr<Matrix<int, 2, 2>> ptrMat2x2 =
std::make_shared<Matrix<int, 2, 2>>( Matrix<int,2,2>( 1, 2, 3, 4 ) );
// accessing the elements from the shared pointer and printing
for( int i = 0; i < 4; i++ )
std::cout << (*ptrMat2x2.get())(i) << ' ';
std::cout << '\n';
// creating some basic shared_ptrs
auto a = std::make_shared<int>( 1 );
auto b = std::make_shared<int>( 2 );
auto c = std::make_shared<int>( 3 );
auto d = std::make_shared<int>( 4 );
// Matrix that holds shared_ptrs
Matrix<std::shared_ptr<int>, 2, 2> mat2x2ptrs( a, b, c, d );
// print the elements from the matrix (don't forget to dereference).
for( int i = 0; i < 4; i++ )
std::cout << *mat2x2ptrs[i].get() << ' ';
std::cout << '\n';
std::cout << "\nPress any key and enter to quit.\n";
std::cin.get();
return 0;
}
答案 2 :(得分:0)
您已经分配了两个单独的数组,您需要以相反的顺序删除两个单独的数组。