从函数返回后调用的析构函数
Destructor called after returning from function
我的大学有一些项目,我需要将一些数据从文件转换为矩阵表示。
主要问题是在返回表单后 "returnNeighbours(int node)" 析构函数在邻居对象上被调用(正如我从 运行 gdb 得出的结论)。
我知道当局部变量在函数中被初始化时总是调用析构函数,但 neihbours 是 class 成员。我不会 post 一切,因为我认为没有必要。我在下面列出了一些结构。
representation.cpp
NodeContainer::NodeContainer(){ size = 0; array = nullptr; }
NodeContainer::~NodeContainer(){ size = 0; delete[] array; }
void NodeContainer::allocateMemoryAndSetSize(int n){ size = n; array = new int[size]; }
void MatrixRep::convertDataToMatrixRep(int** array)
{
for(int i = 0 ; i != size; i++)
for(int j = 0; j != size; j++)
matrix[i][j] = array[i][j];
}
NodeContainer MatrixRep::returnNeighbours(int node)
{
deleteNeighboursIfAny();
if(!checkIfNotBeyondMatrix(node))
return neighbours;
neighbours.allocateMemoryAndSetSize(countNeighbours(node));
for(int i = 0, j = 0; i < size; i++)
if(matrix[node-1][i] != 0)
{
neighbours.array[j] = matrix[node-1][i];
j++;
}
return neighbours;
}
void MatrixRep::deleteNeighboursIfAny(){ if(neighbours.array) neighbours.~NodeContainer(); }
bool MatrixRep::checkIfNotBeyondMatrix(int node)
{
if(node == 0 || node > size)
{
std::cerr<<"There is no such a node!\n";
return false;
}
else
return true;
}
int MatrixRep::countNeighbours(int node)
{
int count_non_zero = 0;
for(int i = 0; i != size; i++)
if(matrix[node-1][i] != 0)
count_non_zero++;
return count_non_zero;
}
representation.h
struct NodeContainer
{
int size;
int* array;
NodeContainer();
~NodeContainer();
void allocateMemoryAndSetSize(int);
};
class MatrixRep
{
int size;
NodeContainer neighbours;
int** matrix;
public:
MatrixRep(int);
~MatrixRep();
void convertDataToMatrixRep(int**);
NodeContainer returnNeighbours(int);
void deleteNeighboursIfAny();
bool checkIfNotBeyondMatrix(int);
int countNeighbours(int);
void setupMatrix();
void deleteMatrix();
};
如果您想 return NodeContainer 的副本,您 必须 为它实现复制构造函数和赋值运算符。如果您使用的是符合 C++11 标准的编译器,那么还可以实现移动构造函数和移动赋值运算符。
另一方面,如果您不想创建副本,则必须return一个指针或对成员的引用。您还可以将成员设置为 std::shared_ptr,在这种情况下您可以 return。
但是,在您当前的实现中,您实际上是在 returning NodeContainer 的 shallow 副本。一旦你的副本超出范围,它的析构函数就会被调用,它会释放它的内存,在这种情况下是你的成员的原始内存,有效地使你的成员无效。实施并不像现在这样好。因此,根据您的目标,要么实施第一个建议的解决方案,要么实施第二个。
我的大学有一些项目,我需要将一些数据从文件转换为矩阵表示。
主要问题是在返回表单后 "returnNeighbours(int node)" 析构函数在邻居对象上被调用(正如我从 运行 gdb 得出的结论)。
我知道当局部变量在函数中被初始化时总是调用析构函数,但 neihbours 是 class 成员。我不会 post 一切,因为我认为没有必要。我在下面列出了一些结构。
representation.cpp
NodeContainer::NodeContainer(){ size = 0; array = nullptr; }
NodeContainer::~NodeContainer(){ size = 0; delete[] array; }
void NodeContainer::allocateMemoryAndSetSize(int n){ size = n; array = new int[size]; }
void MatrixRep::convertDataToMatrixRep(int** array)
{
for(int i = 0 ; i != size; i++)
for(int j = 0; j != size; j++)
matrix[i][j] = array[i][j];
}
NodeContainer MatrixRep::returnNeighbours(int node)
{
deleteNeighboursIfAny();
if(!checkIfNotBeyondMatrix(node))
return neighbours;
neighbours.allocateMemoryAndSetSize(countNeighbours(node));
for(int i = 0, j = 0; i < size; i++)
if(matrix[node-1][i] != 0)
{
neighbours.array[j] = matrix[node-1][i];
j++;
}
return neighbours;
}
void MatrixRep::deleteNeighboursIfAny(){ if(neighbours.array) neighbours.~NodeContainer(); }
bool MatrixRep::checkIfNotBeyondMatrix(int node)
{
if(node == 0 || node > size)
{
std::cerr<<"There is no such a node!\n";
return false;
}
else
return true;
}
int MatrixRep::countNeighbours(int node)
{
int count_non_zero = 0;
for(int i = 0; i != size; i++)
if(matrix[node-1][i] != 0)
count_non_zero++;
return count_non_zero;
}
representation.h
struct NodeContainer
{
int size;
int* array;
NodeContainer();
~NodeContainer();
void allocateMemoryAndSetSize(int);
};
class MatrixRep
{
int size;
NodeContainer neighbours;
int** matrix;
public:
MatrixRep(int);
~MatrixRep();
void convertDataToMatrixRep(int**);
NodeContainer returnNeighbours(int);
void deleteNeighboursIfAny();
bool checkIfNotBeyondMatrix(int);
int countNeighbours(int);
void setupMatrix();
void deleteMatrix();
};
如果您想 return NodeContainer 的副本,您 必须 为它实现复制构造函数和赋值运算符。如果您使用的是符合 C++11 标准的编译器,那么还可以实现移动构造函数和移动赋值运算符。
另一方面,如果您不想创建副本,则必须return一个指针或对成员的引用。您还可以将成员设置为 std::shared_ptr,在这种情况下您可以 return。
但是,在您当前的实现中,您实际上是在 returning NodeContainer 的 shallow 副本。一旦你的副本超出范围,它的析构函数就会被调用,它会释放它的内存,在这种情况下是你的成员的原始内存,有效地使你的成员无效。实施并不像现在这样好。因此,根据您的目标,要么实施第一个建议的解决方案,要么实施第二个。