[英]Memory leak when creating/accessing nodes in n-ary tree
我從以下代碼獲取內存泄漏:
struct Node {
Node *children[20];
int value;
Node();
~Node();
};
Node::Node() {
for(int i=0; i<20; i++) {
children[i] = NULL;
}
}
void Node::insert(int x) {
Node *n = this;
for(int i=0; i<20; i++) {
if(n->children[i] == NULL) {
n->children[i] = new Node();
n->children[i]->value = x;
}
n = n->children[i];
}
}
檢查Valgrind,顯然我從這條線泄漏:
n->children[i] = new Node();
這是使用構造函數的錯誤方法嗎?
還是Valgrind支票有誤導性?
Valgrind錯誤消息:
505 (448 direct, 57 indirect) bytes in 2 blocks are definitely lost in loss record 2 of 3
at 0x4C2B1C7: operator new(unsigned long)
by 0x401A4F: Node::insert
by 0x4015FA: main
LEAK SUMMARY:
definitely lost: 448 bytes in 2 blocks
indirectly lost: 57 bytes in 2 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 72,704 bytes in 1 blocks
suppressed: 0 bytes in 0 blocks
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
我擁有的析構函數:
Node::~Node() {
for(int i=0; i<20; i++) {
delete children[i];
children[i] = NULL;
}
}
在主要方面:
int main() {
Node *n = new Node();
.
.
.
delete n;
n = NULL;
return 0;
}
您沒有刪除孩子。 正如Axel回答的那樣,您應該在析構函數中添加一個刪除。 或更妙的是,使用unique_ptr數組,該數組將在節點超出范圍時銷毀節點。
您永遠不會刪除子指針。
您應該刪除Node類析構函數中子數組的每個分配指針。
像那樣 :
Node::~Node()
{
for (int i = 0; i < 20; ++i)
{
delete children[i];
}
}
此外,如果還有其他方法可以替換子數組中的指針,則必須先刪除之前的指針,然后再執行以下操作:
...
delete n->children[i];
n->children[i] = new Node();
...
要么
...
delete n->children[i];
n->children[i] = p; // where p is a pointer of Node
...
有關信息,您必須調用delete來銷毀和釋放在堆上構造的每個對象(使用new )。
您也可以使用smartpointer來避免管理兒童成員的破壞。
我看到一個新的,但沒有刪除的指針,也沒有智能指針。 這意味着您無需分配內存就可以分配內存。 (至少您沒有向我們展示Node
的析構函數應該在哪里進行。)
除此之外,您的代碼還有一些缺陷:
使用智能指針分配內存:
struct Node {
unique_ptr<Node> children[20]; //consider switching to std::array
int value;
// no destructor needed, because unique_ptr takes care of itself
Node (int newValue);
void insert(int valueToInsert);
};
void Node::insert(int valueToInsert) {
auto freeSpot = //find the point where you want to insert the new node
if ( /*freeSpot is a valid location*/ )
*freeSpot = make_unique<Node>(x);
}
Node::Node(int newValue)
: value(newValue)
{}
那將是您可以做的第一個重構
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.