删除类中的动态二维数组时,C++ 不断出现“中止(核心转储)”

Posted

技术标签:

【中文标题】删除类中的动态二维数组时,C++ 不断出现“中止(核心转储)”【英文标题】:C++ Keep getting "Aborted (core dumped)" when deleting dynamic 2D Array inside a class 【发布时间】:2018-03-31 03:11:36 【问题描述】:

/*编辑:我不确定我是否做错了什么,但一些 cmets 和反对票让我觉得问一个简单的问题真的很愚蠢。

我很欣赏建设性的批评,因为我是一个完整的编码新手。对于那些提供帮助的人,我真的很感激,我确实学到了很多。

我只是希望你们中的一些人在回答我的问题时不要那么粗鲁。哦,好吧,请投反对票。 */

大家好,这是我在这里的第一个问题!我创建了一个简单的 Array 类,它允许用户创建具有指定行和列的动态二维数组。在调用析构函数之前一切正常,我尝试删除动态创建的数据数组。

我将提供我的头文件和实现文件:

/* Array.h
 * Array Class Header File
 */

#ifndef ARRAY_H
#define ARRAY_H

class Array
  private:
    int row;
    int col;
    int **data;
  public:
    Array(int,int);
    ~Array();
    int getRow()  return row;
    int getCol() return col;
    int getData(int,int);

;

#endif




/* Array.cpp
 * Array implementation file
 */

#include <iostream>
#include <cstdlib>
#include "Array.h"

using namespace std;

//Constructor
Array::Array(int rowIn,int colIn)
// RowIn and ColIn must be greater than 1 to create matrix
  if(rowIn <= 1 || colIn <= 1)
    cout << "Row and column must be greater than 1" << endl;
    return;
  
// If they are greater than 1 then set member variables
  row = rowIn;
  col = colIn;

// Allocate memory for 2D Array
  data = new int*[row];
  for(int i = 0; i < row; i++)
    data[i] = new int[col];
  

// Fill 2D array with random numbers
  for(int i = 0; i < row; i++)
    for(int j = 0; j < col; j++)
      data[i][j] = rand()%90 + 10;
    
  



// Getter function that returns data at row and col
int Array::getData(int row,int col)
  return data[row][col];


//Destructor
Array::~Array()
  for(int i = 0; i < row; i++)
    delete[] data[i];
  

  delete []data;




/* Main.cpp
 * File to test array class
 * 
 */
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "Array.h"

using namespace std;

void printArray(Array);

int main()
  int t = time(0);
  srand(t);

  Array test(10,10);

  printArray(test);

  return 0;


void printArray(Array a)
  for(int i = 0; i < a.getRow(); i++)
    for(int j =0 ; j < a.getCol(); j++)
      cout << a.getData(i,j) << " ";
    
    cout << endl;
  

【问题讨论】:

上面的代码位没有错误。请提供minimal reproducible example。可能你打破了三法则。如果无效参数传递给构造函数,您的析构函数也会尝试删除未分配的内存。它应该抛出异常而不是返回。 请发布您如何使用此Array 课程,即main 程序。另外——在调用析构函数之前一切正常——不正确——析构函数没有任何问题,因为它正在做它应该做的工作。问题是你在调用析构函数之前破坏了你的对象。 我提供了一个主程序给你看。我真的做的不多。我只是在创造、打印、然后破坏,我不知道我做错了什么。 好吧,您最近的编辑显示了错误。 void printArray(Array a) 您正在通过值传递Array,因此将发生复制。您的 Array 类不能安全复制。编写具有成员作为指向动态分配内存的指针的类现在不是那么简单了,是吗?阅读the rule of 3/5/0 哇哦,你是对的。我通过引用传递,错误消失了。但是我不完全理解为什么这会导致问题?我不是只是创建一个要打印的副本而不是实际更改数组对象吗? 【参考方案1】:

您需要将您的打印函数声明为void printArray(Array&amp; a),否则,数组在传递时会被复制(C 和C++ 中的默认值是按值传递=复制)。

因此,在调用 print 之后,副本释放所有指针(正确),然后原件再次执行 - 相同的数据 - 这是未定义的行为。

【讨论】:

【参考方案2】:

如果你不想做很多事情,删除复制构造函数和赋值运算符:

Array(const Array&) = delete;
const Array& operator= (const Array&) = delete;

同时更改声明和定义

void printArray(const Array &a);

还要小心构造函数。如果通过参数将 0 或 1 传递给当前实现,则会留下未初始化的对象,并且进一步的析构函数将中止。

【讨论】:

以上是关于删除类中的动态二维数组时,C++ 不断出现“中止(核心转储)”的主要内容,如果未能解决你的问题,请参考以下文章

利用c++中的vector创建动态二维数组

C++中动态二维数组中的地址

二维数组C++的动态分配

在 C++ 中的 2D 动态内存分配数组中释放分配的内存

如何使用 C++ 中的指针动态分配和解除分配二维数组?

指向 C++ 中动态分配的二维数组中的一行的指针