2013-11-21 112 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來返回它。否則,你會得到未定義的行爲。