c++ - 将二维数组插入 vector 并删除数组,但会导致段错误

标签 c++ class pointers matrix vector

我有一个名为 Matrix 的类。类中有一个二维数组用来保存数据。

    template <class Type>
    class Matrix{
        public:
           Matrix(int row, int col){
             rows = row; cols = col;
             data = new Type*[rows];
             for(int i = 0; i < rows; i++){
              data[i] = new Type[cols]; 
              }
           }
      public: 
         int rows;
         int cols;
         Type **data;
    };

我有一个 vector 来保存矩阵。每次有一个Matrix,我都会把这个vector中的matrix往后推,以便以后计算。为了避免内存泄漏,我想在将 Matrix 推回 vector 后将其删除。但是如果我不删除它,程序就可以运行;如果我删除它(如下面的代码所示),当我想对该 vector 进行一些计算时,程序将显示段错误。我使用的代码如下所示

    vector<Matrix<int>> v; 
    for(int i = 0; i < 10; ++i){
         Matrix<int> a(3,3);
                 ...... // I fill the elements of a.data
       v.push_back(a);
       for(int j = 0; j < a.rows; ++j)
             delete[] a.data[j];
       delete[] a.data;
    }

希望我已经清楚地解释了我的问题。如果有什么让您感到困惑,请评论我。

感谢帮助!!!

最佳答案

我在您的代码中发现了多个问题:

  • 它是 C++,你手动为矩阵分配内存,为什么?
  • 即使您有权访问析构函数,您也不会实现它,但您会在主代码中手动删除矩阵的数据
  • 你的方法没有清楚地管理内存,当你按值 push_back 时,Matrix 被复制到 vector 中,此时谁拥有数据的指针?堆栈上的拷贝还是 vector 中的拷贝?

您应该通过为类实现正确的复制构造函数、复制赋值运算符和析构函数来小心管理内存。

但这无关紧要,因为您可以只使用 C++ 功能而忘记这些问题,一些解决方案:

在 vector 中存储指针

class Matrix{
public:
  Matrix(int row, int col){
    rows = row; cols = col;
    data = new Type*[rows];
    for(int i = 0; i < rows; i++){
      data[i] = new Type[cols];
    }
  }
  ~Matrix() {  // you need a destructor
    for (int i = 0; i < rows; ++i)
      delete[] data[i];
    delete data;
  }
public:
  int rows;
  int cols;
  Type **data;
};

std::vector<std::unique_ptr<Matrix>> v;
Matrix* matrix = new Matrix(3,3);
v.push_back(std::unique_ptr<Matrix>(matrix));

现在矩阵变得持久化,但当 v 超出范围时它们会自动释放(感谢 unique_ptr 和析构函数)

对矩阵元素使用std::vector/std::array

您正在使用它们来存储多个矩阵,为什么不将它们也用于矩阵本身呢?

template<size_t ROWS, size_t COLS, class TYPE>
class Matrix
{
  std::array<std::array<COLS, TYPE>, ROWS> data;
  ...
}

现在一切都是自动管理的,你不需要释放内存,你根本不需要 Matrix 的析构函数。

std::vector<Matrix<3,3,float>> v;
Matrix<3,3,float> m;
v.emplace_back(m);
m.data[0][0] = 1;

如果你想在同一个 vector 中有不同大小的矩阵,或者如果你想保持堆栈使用率低(因为 std::array 不是动态分配的)那么使用 std: :vector 而不是 std::array 以便您可以删除模板参数。

关于c++ - 将二维数组插入 vector 并删除数组,但会导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32489184/

相关文章:

jquery - 将类添加到数组中的第一个元素

c - 为什么 C 中的数组会衰减为指针?

c++ - 从字符串中删除空格 - 带指针的就地 C 样式

c++ - 在 iPhone 上使用现有的 C++ 引擎

c++ - 使用 XInput 延迟 Xbox360 游戏 handle 的轮询事件

class - 添加或删除带有原型(prototype)的类

swift - 如何覆盖父类(super class)中的私有(private)变量

c++ - 修剪空格 C++ POINTERS

c++ - 无法弄清楚出了什么问题 : "expected primary-expression before ' )' token"

c++ - 在cmake中在find_package中传递多个值