Passing a Pointer into a Function and Modifying it

好久不见. 提交于 2021-02-17 05:21:07

问题


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 newed 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 Nodes such that the data members are zero initialized, use value initialization:

Node* tree = new Node();

Note 2: Be very careful with using raw newed 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!