模板类的破坏者导致分割故障

发布于 2025-01-17 21:50:08 字数 1623 浏览 5 评论 0原文

这是简短版本的模板类,具有重要的方法:

template<class T>
class Matrix
{
protected:
    int width;
    int height;
    T ** values;
public:
    Matrix(int width, int height);
    ~Matrix();
    T get(int i, int j);
    void set(int i, int j, T value);
};

template<class T>
Matrix<T>::Matrix(int width, int height) {
  this->width = width;
  this->height = height;

  this->values = new T*[width];
  for(int i=0; i<width; i++)
    this->values[i] = new T[height];
}

template<class T>
Matrix<T>::~Matrix() {
  cout << "~ 1" << endl;
  for(int i=0; i<this->width; i++) {
    cout << "~ 2" << endl;
    for(int j=0; j<this->height; j++) {
      cout << "~ 3" << endl;
      delete [] &this->values[i][j];
    }
    cout << "~ 4" << endl;
    delete [] &this->values[i];
    cout << "~ 5" << endl;
  }
}

template<class T>
T Matrix<T>::get(int i, int j) {
  return this->values[i][j];
}

template<class T>
void Matrix<T>::set(int i, int j, T value) {
  this->values[i][j] = value;
}

在我的主项目中,每次可执行文件需要从此类中删除对象时,程序都会因分段错误错误而退出。

下面是一个也发生错误的小程序:

int main() {
  cout << "1" << endl;
  Matrix<int> * matrix = new Matrix<int>(300, 300);
  cout << "2" << endl;
  for(int i=0; i<300; i++)
    for(int j=0; j<300; j++)
      matrix->set(i, j, i+j);
  cout << "3" << endl;
  delete matrix;
  cout << "4" << endl;
  return 1;
}

任何人都可以告诉我这个析构函数有什么问题吗?

This is the short version template class, with the important methods:

template<class T>
class Matrix
{
protected:
    int width;
    int height;
    T ** values;
public:
    Matrix(int width, int height);
    ~Matrix();
    T get(int i, int j);
    void set(int i, int j, T value);
};

template<class T>
Matrix<T>::Matrix(int width, int height) {
  this->width = width;
  this->height = height;

  this->values = new T*[width];
  for(int i=0; i<width; i++)
    this->values[i] = new T[height];
}

template<class T>
Matrix<T>::~Matrix() {
  cout << "~ 1" << endl;
  for(int i=0; i<this->width; i++) {
    cout << "~ 2" << endl;
    for(int j=0; j<this->height; j++) {
      cout << "~ 3" << endl;
      delete [] &this->values[i][j];
    }
    cout << "~ 4" << endl;
    delete [] &this->values[i];
    cout << "~ 5" << endl;
  }
}

template<class T>
T Matrix<T>::get(int i, int j) {
  return this->values[i][j];
}

template<class T>
void Matrix<T>::set(int i, int j, T value) {
  this->values[i][j] = value;
}

In my main project, every time the executable needs delete an object from this class, the program exits with a segmentation fault error.

Below a small program where the error also occurs:

int main() {
  cout << "1" << endl;
  Matrix<int> * matrix = new Matrix<int>(300, 300);
  cout << "2" << endl;
  for(int i=0; i<300; i++)
    for(int j=0; j<300; j++)
      matrix->set(i, j, i+j);
  cout << "3" << endl;
  delete matrix;
  cout << "4" << endl;
  return 1;
}

Anyone can tell me what's wrong with this destructor?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心奴独伤 2025-01-24 21:50:08

您的破坏者编码错误。

每个new []需要一个相应的delete []。您的构造函数调用new [] 1次分配values的第一维> values的第二维度的时间。

因此,您的驱动器需要调用delete [] width width times times times times times times times times times for 1st维,例如:

template<class T>
Matrix<T>::~Matrix() {
  cout << "~ 1" << endl;
  for(int i=0; i<width; i++) {
    cout << "~ 2" << endl;
    delete[] values[i];
  }
  cout << "~ 3" << endl;
  delete[] values;
}

还请注意,您的矩阵 class不关注 3/5/0的规则管理value Pointer 正确,因为它缺少复制构造函数和复制分配运算符,以及移动构造函数和移动分配操作员。因此,如果您的矩阵对象被复制/移动,这将导致破坏者问题。

Your destructor is coded wrong.

Each new[] needs a corresponding delete[]. Your constructor calls new[] 1 time to allocate the 1st dimension of values, and then calls new[] width times for the 2nd dimension of values.

As such, your destructor needs to call delete[] width times for the 2nd dimension, and call delete[] 1 time for the 1st dimension, eg:

template<class T>
Matrix<T>::~Matrix() {
  cout << "~ 1" << endl;
  for(int i=0; i<width; i++) {
    cout << "~ 2" << endl;
    delete[] values[i];
  }
  cout << "~ 3" << endl;
  delete[] values;
}

Also be aware that your Matrix class is not following the Rule of 3/5/0 to manage the value pointer correctly, as it lacks a copy constructor and copy assignment operator, and a move constructor and move assignment operator. So that will cause problems for your destructor if your Matrix objects are ever copied/moved.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文