【问题标题】:c++ Struct pointer unable to read memory when initialised as NULLc++ Struct指针初始化为NULL时无法读取内存
【发布时间】:2018-09-02 07:31:29
【问题描述】:

我正在创建一个包含二叉搜索树算法的程序,但我遇到了一个不知道如何解决的问题。这是我的代码的相关部分。

struct node {
    string data;
    node *left = NULL;
    node *right = NULL;
};

这就是我的节点结构。

void Insert_Rec(string word, node* ptr) {

if (ptr->data == "") {

    ptr->data = word;
    ptr->left = NULL;
    ptr->right = NULL;
    cout << "overwitten!" << endl;
}
else if (word < ptr->data) {
    if (ptr->left != NULL) {
        cout << "Recursing left!";
        Insert_Rec(word, ptr->left);
    }
    else {
        ptr->data = word;
        ptr->left = NULL;
        ptr->right = NULL;
        cout << "Inserted!";
    }
}

问题就出在这里,程序永远不会进入 if(ptr->left != NULL) 语句。查看我的 Visual Studio 调试器,ptr->left 显示“”而不是 NULL。我该如何解决这个问题!?我在这里尝试了其他一些解决方案,但它们要么不相关,要么根本不起作用!!

【问题讨论】:

  • 您应该在取消引用指针之前检查nullptr
  • 解决方案将使用调试器逐行逐步执行代码,查看all 变量,并将它们与您的期望进行比较。
  • 为了让程序采用(ptr-&gt;left != NULL) 分支,您必须在某处将ptr-&gt;left 设置为NULL 以外的值。你永远不会这样做。
  • 您是否在某处为ptr-&gt;left 分配了非空值?您应该显示完整的代码。
  • 我建议使用std::string::empty 而不是与“”比较。

标签: c++ string pointers binary-search-tree


【解决方案1】:

程序从不进入 if(ptr->left != NULL) 语句

ptr-&gt;left 以 NULL 开头,您永远不会为它分配任何其他内容,因此它将永远保持为 NULL。

if (ptr->left) {
    cout << "Recursing left!";
    Insert_Rec(word, ptr->left);
}
else {
    /* this just overwrites the existing node in-place
       but you should be creating a new node for the left child
    ptr->data = word;
    ptr->left = NULL;
    ptr->right = NULL;
    */
    ptr->left = new node{word, nullptr, nullptr};
    cout << "Inserted!";
}

您的代码还有许多其他问题(Vlad-from-Moscow 的回答显示了此功能的更好设计,但您确实需要在容器类级别修复它),但这是直接的障碍。

【讨论】:

    【解决方案2】:

    你的函数实现在整体上没有意义。

    函数可以通过以下方式定义

    void Insert_Rec( node **head, const std::string &word ) 
    {
        if ( *head == nullptr )
        {
            *head = new node { word, nullptr, nullptr };
        }
        else if ( word < ( *head )->data )
        {
            Insert_Rec( &( *head )->left, word );
        }
        else
        {
            Insert_Rec( &( *head )->right, word );
        }
    }  
    

    如果需要,该函数应该分配一个新节点。

    如果您希望 BST 不包含重复项,请将最后一个 else 语句更改为 else if 语句,如

    else if ( ( *head )->data < word )
    

    函数可以通过以下方式调用

    node *head = nullptr;
    //...
    Insert_Rec( &head, "Hello" );
    

    您还可以使用引用类型作为第一个函数参数的类型,而不是“双”指针。

    例如

    void Insert_Rec( node * &head, const std::string &word ) 
    {
        if ( head == nullptr )
        {
            head = new node { word, nullptr, nullptr };
        }
        else if ( word < head->data )
        {
            Insert_Rec( head->left, word );
        }
        else
        {
            Insert_Rec( head->right, word );
        }
    } 
    

    【讨论】:

      【解决方案3】:

      您在结构中设置了节点 *left=NULL 和节点 *right=NULL。删除那个NULL。只留下两个指针。否则,它只是空的。无论如何,请记住,您很少需要初始化结构中的指针。

      struct node {
          // simple is better (-:
          string data;
          struct node *left;
          struct node *right;
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-17
        • 2015-11-08
        • 2017-09-06
        • 1970-01-01
        • 1970-01-01
        • 2023-01-22
        • 1970-01-01
        相关资源
        最近更新 更多