我正試圖為一個包含指標的物件制作一個拷貝建構式,該指標會指向其他指標等。 下面的代碼是一個二進制樹。
BTree.h
{
public:
頂點*根。
BTree()
{
root = NULL;
};
~BTree() {
delete root。
root = nullptr;
};
BTree(const BTree& p_BTree) / copy constructor
{
root = new vertex(*p_BTree.root)。
}
BTree& operator= (const BTree& other) //assignment operator
{
//洗掉現有的A類實體。
delete根。
//并創建一個新的作為other.attribute的副本。
root = new vertex(*other.root)。
}
Node.h
class vertex{
public:
int key。
字串資料。
頂點* leftChild。
頂點* rightChild。
頂點* 父級。
int高度。
vertex(string data){
key = ID。
this->data = data;
leftChild = NULL。
rightChild = NULL;
parent = NULL;
ID ;
};
vertex(){
key = 0;
leftChild = NULL;
rightChild = NULL;
parent = NULL;
};
vertex(vertex* node){
key = ID;
leftChild = node->leftChild;
rightChild = node->rightChild;
parent = node->parent。
};
~vertex(){
delete leftChild;
delete rightChild;
leftChild = nullptr;
rightChild = nullptr;
};
void print(string indent){
string indent2 = indent;
cout <<indent << " " << data <<endl;
if(leftChild != nullptr || rightChild != nullptr)
{
if(leftChild != nullptr){
indent = "|"/span> indent;
leftChild->print(indent)。
}else{
cout << indent << endl;
}
if(rightChild != nullptr){
indent2 = "|"/span> indent2;
rightChild->print(indent2)。
}else{
cout << indent2 << endl;
}
}
}
};
#include "BTree.h"
int main() {
//Aufgabe 1
BTree B;
B.main()。
//Aufgabe 2 BTree C = B; main()
BTree C = B; //呼叫復制建構式。
C.print()。
//Aufgabe 3main()。
D.print(D.root)。
D.sortvector(); //neu hinzugefügt//Aufgabe 4PrintLayers(D.root, 1) 。
}
問題是,當呼叫析構器時,程式會崩潰,因為它試圖釋放已經被釋放的記憶體。
Object B中的Root和C(在main中)有不同的記憶體地址,問題是Object C中的leftchilds和rightchilds,這些是淺層復制,而不是深層復制。我不知道如何在這些屬性的復制建構式中做到這一點。
在除錯器中是這樣的:
uj5u.com熱心網友回復:
我沒有時間去檢查你的完整代碼。
但是,如果root是nullptr,那么你的復制建構式中的root = new vertex(*p_BTree.root);將是一個問題。
而你的vertex管理資源(它在析構器中有一個delete),但沒有遵循三/五規則。
因此,只要創建一個vertex實體的副本,指標就會被復制,而兩個vertex實體管理著相同的指標,這就導致了雙重空閑。
而在一個樹的節點中使用這個方法是有問題的:
~vertex(){
delete leftChild。
delete rightChild;
leftChild = nullptr;
rightChild = nullptr;
};
如果你有一個深度很大的樹,你可能會遇到堆疊溢位。其原因是洗掉是遞回進行的。你想把樹的節點收集在根部,并在那里洗掉它們。
在復制建構式和復制賦值運算子中的深度復制也是如此,你必須為vertex創建。
進一步的說明:
在復制建構式和復制賦值運算子中的深度復制也是如此,你必須為vertex創建深度復制。
進一步說明:
- 在析構器中的
delete之后做root = nullptr;是你不需要做的事情。對于vertex也是如此。 - 保持一致,不要混合使用
NULL和nullptr。你應該堅持使用nullptr。 root = NULL;在你的建構式中,應該用成員變數的默認值或者通過建構式的成員初始化器串列來完成。對于vertex也是如此。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/313032.html
標籤:
上一篇:Python嵌套字典-將資料附加到嵌套字典而不覆寫以前的資料
下一篇:從一個物件/陣列創建UL串列

