将指针传递给函数并进行修改

时间:2014-02-05 06:31:58

标签: c++ function pointers

stackoverflow和C / C ++都是新手。我正在实现一个二叉树,并有一个简单的问题。可以说我有以下内容:

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
}

非常简单吧。它会崩溃,因为即使从addNode返回后,树仍然是NULL。我试图理解的是为什么一旦调用addNode就不会更新它。当然,指针的副本被使用和更新,但它不应该仍然保持相同的地址吗?因此,仍然更新原始内存地址并返回。或者由于某种原因新指针指向不同的位置?我对发生的事感到困惑。任何帮助都会很棒。

另外,我刚刚在网站上写了这个代码 - 抱歉,如果没有什么错误,实际上没有运行它。

感谢。

3 个答案:

答案 0 :(得分:4)

有一些问题,

首先,你有一个指针addNode的本地副本,你没有取消引用它来对它指向的东西采取行动,而是直接作用于本地指针本身。在函数内部创建的new ed Node将永远丢失。

您可以通过引用传递指针来解决该问题。这不需要对您的代码进行任何其他修改:

void addNode(Node*& tree, int new_data)

其次,如您所述,您正在main中取消引用NULL指针。这只是未定义的行为(UB)。可能发生的事情之一是崩溃。但代码可以只是静默运行而不会崩溃。重要的是它是UB并且不能依赖程序。

注1 :如果要初始化Node以使数据成员初始化为零,请使用值初始化

Node* tree = new Node();

注意2 :使用原始new指针时要非常小心。您的代码中已经有一个 两个资源泄漏。更好地使用最合适的智能指针类型。

答案 1 :(得分:1)

由于您将指针传递给addNode

中的树
void addNode(Node* tree, int new_data)

声明

tree = new_tree;

只是本地的,你不会改变传递指针所指向的内容,因为树是指针的副本。

比较
void foo(int n) {  n = 1; }   // local, n is a copy
void foo(int* n) { *n = 1; }  // change the original variabel

为了改变你需要传递指针地址的树点

void addNode(Node** tree, int new_data)
{
...
   *tree = new Node;
...
}

答案 2 :(得分:-1)

如果要保持更改反映在main函数中(对于指针或非指针变量),安全方式是通过引用传递,因为引用变量只能初始化一次

即:

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
}

所以最安全的方法是通过引用传递,我的意思是void addNode(Node*& tree, int new_data)