【问题标题】:C++ problems with pointers while creating Nodes创建节点时指针的 C++ 问题
【发布时间】:2014-03-02 07:11:10
【问题描述】:

所以我试图使用一些我必须使用的给定函数将 BST 转换为 DLL。在这样做的同时,我不断遇到分段错误。当我尝试调试它时,我终于想到了这一点。我在下面写了一个非常简单的测试脚本。

我对指针的了解是它是通过引用传递的,就像我正在更改传递的指针指向的值/对象一样,它会反映在我原来的调用函数中。

为什么当我创建一个新节点然后传递指针(myf)时,它可以工作,但是当我只是传递指针并在函数内部创建新节点时,它显示分段错误(myf2)?

如果这是因为新节点超出范围,请再次检查函数“myf”。我创建了一个新节点,它由我的原始节点指向。并且 this 的值在函数调用结束后保留​​。那这不是也超出范围了吗?

我对它出现的指针有一些基本的基本问题,这真的很有帮助。谢谢

#include<iostream>
using namespace std;

class Node
{
public:
    int val;
    Node *left;
};

void myf(Node *a)
{
    a->left = new Node();
    a->left->val = 20;
    a->val = 15;
}

void myf2(Node *a)
{
    a = new Node();
    a->val = 35;
}

int main()
{
    Node *a = NULL, *b = NULL;
    a = new Node();
    a->val = 5;
    myf(a);
    cout << "New value of a = " << a->val << endl;
    cout << "left value of a = " << a->left->val << endl;
    myf2(b);
    cout << "New value of b = " << b->val << endl;
}

【问题讨论】:

  • right 指针在哪里?
  • 忽略我在 Node() 之后给出的括号。初始化时不需要。
  • 嗨 Rikayan。这是一个测试代码。这个程序没有任何逻辑或动机。我正处于一个更复杂的代码中间,所以我编写了这个测试代码来找出问题所在。请专注于这里的一切。谢谢。

标签: c++ pointers


【解决方案1】:

您的问题是,您的指针未设置为 b,为此,您需要将 myf2 编辑为如下内容:

void myf2(Node **a)
{
    *a = new Node();
    (*a)->val=35;
}


然后像这样调用myf2

myf2(&b);


我相信这应该可以解决你的问题。


不要将Node *b 仅视为一个指针,也应将其视为一个整数,因为指针分解为一个指向内存空间的整数。

所以你传递了一个指向函数的指针(整数)的指针。

另一个例子是:

void myfunction(int *i) {
    *i = 5;
}

int main(int argc, char** argv) {
    int x;
    myfunction(&x);
    cout << x << endl;
    return 0;
}

但那是使用一个实际的整数。

【讨论】:

  • 嗨,大卫。但是 myf2 中的 *a 基本上仍然是指向对象的指针,对吧?你是怎么给它分配Node的?
  • @user3370135 是的,它是一个指针,您可以将一个 Node 对象分配给*a,如示例所示。 a 是指向指针的指针,*a 是指针本身。 (*a) = new Node();
  • @user3370135 我通过传递指针本身的内存地址给它分配了节点,大多数操作系统是integer,我将新分配的对象存储到传递给的指针的内存中函数。
  • 明白。非常感谢:)
【解决方案2】:

为什么我新建一个Node,然后传指针(myf)就可以了,

节点 *a: main() 使它指向一个内存块,您将该地址传递给myf,您更新该块中的内存。有效!

但是当我只是传递指针并在函数内创建新节点时,它显示分段错误(myf2)?

节点 *b: main() 没有分配任何东西,它指向NULLmyf2() 只获取NULL 的地址,然后创建另一个指针b(与main() 中的不同),使其指向某个内存块,但它不会更新您在main() 中的原始b 指向的内容,它仍然指向NULL。因此SEGFAULT

基本上你正在尝试两种不同的有效方法,这是正确的方法:

案例 1。

main()
{
    Node* a = NULL;
    a = new Node();  //make 'a' point to some valid block of memory
    myf(a);    // here you are passing the address of the memory block of type Node
    cout << "New value of a = " << a->val << endl; //and this is valid since 'a' points to a valid address
}

void myf(Node *a)
{
    a->left = new Node();  
    a->left->val = 20;  // Since the address that you got here is valid, you can make changes here, and in main() Node* a is aware of this address 
    a->val = 15; 
}

案例 2。

main()
{
    Node* b = NULL;
    myf2(&b);   // here since b points to NULL, you have to send the address where this NULL is stored so that the called functon can upadte this NULL to something meaningful
    cout << "New value of b = " << b->val << endl; // this is correct, because we changed what 'b' pointed to from NULL to a valid block of memory of type 'Node'
}

void myf2(Node **a)  //It is a double pointer here because you need to update what it points to, curently it holds NULL
{
    *a = new Node();  // Make it point to a valid address, remember main() has track of 'a', 
    *a->val = 35;  // Now if you make any changes to the blok that 'a' points to, main() will have account of it
}

【讨论】:

  • 解释正是我想要的。非常感谢。说得通。但是在 myf 中,我正在为 b->left 创建一个新节点,我是不是也更改了地址?为什么会反映出来?
  • 查看更新的评论。 main 和 fn myf2 中的变量 b 不一样。
  • 希望更新的答案对您有所帮助,如果您仍有疑问,请发表评论。
  • 我刚刚明白了。所以基本上,如果我从 main 传递一个指向 b 的指针,则会制作该地址的副本并将其存储在 myf 中的 a 指针中。现在,如果我更改 a 指向的地址本身,则不会在我的 main 函数中反映回 b 。但是,我可以更改存储在地址 a 中的值/对象。并且地址a包含一个指向左的指针,所以如果我更新左,那会在我的主函数b中更新。对吗?另外,为了克服这个问题,我是否应该像 David 那样使用指向指针的指针传递它?或者像 Abhay 使用参考?两者都应该工作正常
  • 但是一般来说哪个更容易处理?他们中的任何一个有什么问题吗?我个人觉得指针指向的指针对我来说会更容易处理。
【解决方案3】:

您需要返回您已动态分配内存的Node *a 的引用。

Node* myf(Node *a)

{

    a->left = new Node();

    a->left->val=20;

    a->val=15;

    return a;
}

main ()

a = myf(a);

以前main() 中的a 没有指向在myf() 函数中分配的内存...

【讨论】:

  • 嗨哈德。不错的答案。但实际上我必须返回一个 void,因为我正在使用递归函数并且还涉及其他因素。我认为大卫在下面的回答会很好。我完全忘记了通过引用传递的东西。无论如何,非常感谢您的努力。
【解决方案4】:

通过以下引用接收您的Node ptr..

void myf2(Node *&a) //<-- Notice & in function signature.

在您当前的代码中,您通过值传递 a (Node*),因此,函数中所做的任何更改都不会反映在函数之外,访问 b-&gt;val (null ptr 访问) 将是段错误

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2021-02-19
    • 2021-05-24
    • 2017-05-29
    • 2021-07-23
    • 1970-01-01
    相关资源
    最近更新 更多