2013-11-21 110 views
1

由于某种原因,我的节点似乎并未被删除。它看起来好像遍历到了最后,但是在节点被“删除”之后,它仍然有数据在其中。我也试过 free(bNode)bNode = NULL而不是delete bNode,但他们都给出了相同的结果。C++删除整个二叉搜索树

当我试图调试时,cout和显示功能才放入。我只是不明白为什么它不工作,我希望我不会错过简单的东西。

struct 
Book{ 
char title [50]; 
char url [75]; 
Book *left; 
Book *right; 
}; 

void deleteAllBooks (Book *bNode){ 
    if(bNode==NULL) return;            
    if(bNode->left !=NULL){ 
     cout << endl << "deleting left" << endl; 
     deleteAllBooks(bNode->left); 
    } 
    if(bNode->right !=NULL){ 
     cout << endl << "deleting right" << endl; 
     deleteAllBooks(bNode->right); 
    } 
    cout << endl << "deleting node " << bNode->title << endl; 
    delete bNode; 
    displayBookTree(bNode); 
} 
void displayBookTree(Book *bNode){ 
    if(bNode==NULL){ 
     cout << "No books" << endl; 
     return; 
    } 
    if(bNode->left !=NULL){ 
     displayBookTree(bNode->left); 
    } 
    if(bNode->right !=NULL){ 
     displayBookTree(bNode->right); 
    } 
    cout <<"Title: " << bNode->title << endl; 
    cout <<"URL: " << bNode->url <<endl; 
} 
+1

一方面,delete不会将指针设置为NULL,并且只检查null。 – dutt

+0

我试过使用bNode = NULL,但我仍然有数据...只是再次运行它,数据已从删除函数中的指针中删除,但在函数外部仍有数据传入到指针中删除功能。 hmm – Covertpyro

+0

问题会在'Book'内使用'std :: unique_ptr '离开。所有这些手动内存管理都会使代码难以阅读和脆弱。 – MSalters

回答

2

“使用0。‘NULL’宏不是类型安全的;如果你觉得你必须 使用‘空’,使它成为一个const int的,而不是C风格‘的#define’ 。 请参阅“C++编程语言”,了解Stroustrup针对 使用“NULL”的论点。“

我会努力改变:

if (bNode==NULL) { ... } 

if (!bNode) { ... } 

而且

if (bNode->left !=NULL) { ... } 
if (bNode->right !=NULL) { ... } 

if (bNode->left) { ... } 
if (bNode->right) { ... } 

然后看看this answer关于如何正确删除一个Struct!

0

最简单的办法:

struct Book{ 
    std::string title; 
    std::string url; 
    std::unique_ptr<Book> left; 
    std::unique_ptr<Book> right; 
}; 

void deleteAllBooks (std::unique_ptr<Book> bNode) 
{ 
    // No code necessary. Literally. But usually you wouldn't even 
    // bother with this function, the default Book::~Book is fine. 
} 
0

你的解决方案是正确的,但你的意见是错误。当你删除一个对象时,析构函数将被执行。在你的情况下,这个析构函数没有明显的副作用,因为所有的数据成员都是普通的旧数据类型,它们本身没有析构函数。在删除对象后使用对象,调用未定义的行为,并且您的观察是“未定义行为”的一种可能的体现。 !

你的测试= 0调用deleteAllBooks()之前是多余的:

void deleteAllBooks (Book *node) 
{ 
    if(node) 
    { 
     deleteAllBooks(node->left);            
     deleteAllBooks(node->right);            
     delete node; 
    } 
} 

不相同,但可能会更容易理解。

并且不要混用free/alloc和free/delete。如果你已经用new分配了一个对象,你必须用delete来返回它。否则,你会得到未定义的行为。