2017-03-13 67 views
0
int main(){ 
Node *root , *temp , *temp_before; 
root = new Node(0 , NULL , NULL , NULL); 
temp_before = root; 
temp = temp_before->left; 
temp = new Node(5 , NULL , NULL , NULL); 
temp = root->left; 
cout<<temp->val; 
} 

我有一個名爲Node的結構,第一個參數是int,其他的是Node指針。當我想打印root-> left時,它不起作用,程序在我運行時停止。我不知道,也許我正在做一個非常奇怪的事情,希望這會返回一些東西,但是這有什麼問題?二叉樹不接受新節點

+0

你在哪裏設置樹中的一個節點指向'temp'? – NathanOliver

+0

未初始化的本地非靜態變量(如您所擁有的變量)在初始化它們之前具有* indeterminate *值。使用這些未初始化的變量會導致*未定義的行爲*。 –

+3

指向您將root-> left設置爲除null之外任何其他行的行 – pm100

回答

0

讓我們一行看看代碼行:只

struct Node { 
    int val; 
    Node* left; 
    Node* right; 
    Node* parent; 
    Node(int value, Node* left, Node* right, Node* parent): val(value), left(left), right(right), parent(parent){} 
}; 

void main() { 
    Node *root, *temp, *temp_before; 
    root = new Node(0, NULL, NULL, NULL); // root points to the newly allocated memory 
    temp_before = root; //temp_before also points to that memory 
    temp = temp_before->left; // temp points to the left of root, which is null 
    // NOTE: at this point, temp isn't connected to the tree, even if you allocate memory with it. 
    // You only have pointers ("handles") for those memory blocks but you haven't combined them together yet. 
    temp = new Node(5, NULL, NULL, NULL); // This allocated memory for the memory address pointed by temp 
    // temp = root->left; //error 
    root->left = temp; //correct one 
    // Now root->left points to the memory block you allocated with temp 
} 

當使用指針分配內存時,指針指向的內存塊。除非手動將它們連接在一起,否則它們不會成爲連接結構。

這就是你想要做的,但以錯誤的方式。可以這樣想:當你分配內存時,操作系統給你一個主內存的空間。它通過給你一個「引用」到這個內存塊來完成它,這樣你就可以使用那個內存塊。這就是爲什麼指針也被稱爲「句柄」的原因,因爲它們是您與內存塊交互的方式。

在錯誤的行中,您重寫了剛分配的內存的句柄。當你這樣做時,你會失去對該內存塊的訪問權限,直到程序執行結束。這些重寫被稱爲「內存泄漏」,因爲這塊內存是你問的但忘記的東西。

當您執行temp = root->left;,它會覆蓋另一個指針的指針(在這種情況下,一個指向NULL),當您嘗試打印,它給你一個錯誤稱爲null pointer exception,從名字上就可以清楚地看到問題:)

當你過度複雜的事情,你正在嘗試做,這些錯誤發生 往往會發生,尤其是如果你對內存不熟悉。您可以簡化這種代碼的方法是:

void main() { 
    Node* root = new Node(0, NULL, NULL, NULL); // Allocate root 
    root->left = new Node(5, NULL, NULL, NULL); // This line means "add a new node to the left of my root" 

    std::cout << root->val << std::endl; 
    std::cout << root->left->val << std::endl; 
} 

如果上面的實施鬥爭,認爲它是這樣的:

Node* temp = new Node(5, NULL, NULL, NULL); 
root->left = temp; 

此代碼是相同main函數的代碼。可以這樣想:您正在分配一個內存塊並使用句柄temp訪問它。之後,你分配處理的信息到您的根的左節點指針。這樣,即使您無法再訪問temp,也可以通過root->left訪問相同的內存塊。

下面的代碼是你怎麼想的。嘗試思考這兩者之間的差異,一旦你找出它,指針將更有意義:

Node* temp = root->left; 
temp = new Node(5, NULL, NULL, NULL); 
+1

我知道我不應該在堆棧溢出的評論中寫下「謝謝」,但真的非常感謝這個意義深遠的答案!這完全是我在尋找的東西。我在同一時間遇到了關於指針的問題,這也對它有所幫助,非常感謝您爲您提供答案的時間。 –

0

有幾件事。你將需要檢查你的節點是否等於null。你也應該更新你輸出的內容。

node = root; 
while (node != null) 
{ 
    count << node; 
    node = node->left; 

} 
+0

如果node-> left等於null,我應該如何將節點傳輸到node-> left? –

+0

最初將節點設置到頭部,然後遍歷。我更新了我的答案@TahaSümer – Jay266