问题
New to both stackoverflow and C/C++. Im working through implementing a binary tree and have a simple question. Lets say I have the following:
struct Node {
int data;
Node* right_child;
Node* left_child;
};
void addNode(Node* tree, int new_data){
if(tree == NULL){
Node* new_tree = new Node;
new_tree->data = new_data;
new_tree->right_child = NULL;
new_tree->left_child = NULL;
tree = new_tree;
}
}
int main(){
Node* tree = new Node;
tree = NULL;
addNode(tree, 3);
cout << tree->data << endl; //CRASH
}
Pretty simple right. It would crash because the tree would still be NULL, even after the return from addNode. what I have attempted to understand is why it would not be updated once addNode is called. Sure, a copy of the pointer is used and updated, but shouldn't it still hold the same address? Therefore, still update the original memory address and return. Or does the new pointer for some reason point to a different location? I'm confused about what is going on. Any help would be wonderful.
Also, i just wrote that code on the website - sorry if there are little errors, didnt actually run it.
Thanks.
回答1:
There are a few problems,
First, you have a local copy of the pointer addNode
, and you are not de-referencing it to act on the thing it points to, but acting directly on the local pointer itself. The new
ed Node
created inside the function is just lost forever.
You can fix that problem by passing the pointer by reference. This doesn't require any other modifications to your code:
void addNode(Node*& tree, int new_data)
Second, as you noted, you are de-referencing a NULL pointer in main
. This is simply undefined behaviour (UB). One of the things that can happen is a crash. But the code could just run silently without crashing too. The important fact is that is it UB and the program cannot be relied on.
Note 1: If you want to initialize your Node
s such that the data members are zero initialized, use value initialization:
Node* tree = new Node();
Note 2: Be very careful with using raw new
ed pointers. You already have one two resource leaks in your code. Better use the most appropriate type of smart pointer.
回答2:
Due to that you pass the pointer to tree in addNode
void addNode(Node* tree, int new_data)
the statement
tree = new_tree;
will only be local, you are not changing what the passed pointer is pointing to since tree is a copy of the pointer.
compare with
void foo(int n) { n = 1; } // local, n is a copy
void foo(int* n) { *n = 1; } // change the original variabel
in order to change what tree points to you need to pass the address of the pointer
void addNode(Node** tree, int new_data)
{
...
*tree = new Node;
...
}
回答3:
If you want to keep the changes reflected in your main function(for a pointer or a non pointer variable), the secure way is pass it by reference, because reference variables can be initialized only once
i.e :
void addNode(Node*& tree, int new_data)
{
Node* tree_1;
tree = &tree_1 //this can't be done
}
void addNode(Node** tree, int new_data)
{
Node* tree_1;
tree = &tree_1 //this can be done
}
So the safest way is to pass by reference, i mean void addNode(Node*& tree, int new_data)
来源:https://stackoverflow.com/questions/21570181/passing-a-pointer-into-a-function-and-modifying-it