【问题标题】:inserting node (Binary search tree) C插入节点(二叉搜索树) C
【发布时间】:2013-05-10 21:50:34
【问题描述】:

我正在尝试在二叉搜索树中插入一个节点,但遇到了一个小问题。

#include "stdafx.h"
#include <string.h>
#include <stdlib.h>


typedef struct Node{
    char name[100];
    struct Node *pGauche;
    struct Node *pDroit;
}Node;

void getName(char[]);
void copy(Node **, Node *,char[]);
void menu(Node **);
void add(Node **);
void search(char[],Node**, Node **,Node **);
void print(Node **);
void inOrder(Node *);

void main(void)
{
    Node *root = NULL;
    menu(&root);
    system("pause");
}

void menu(Node **root)
{
    for (int i=0;i<10;i++)
    {
        add(root);
    }
    print(root);
}

void add(Node **root)
{
    char name[100];
    getName(name);
    Node *p = NULL;
    Node *savep = NULL;
    search(name,root,&p,&savep);
    copy(root,savep,name);
}

void search(char name[],Node **root, Node **p, Node **savep)
{
    *p = *root;

    while ((p == NULL) && (strcmp((*p)->name,name) != 0))
    {
        *savep = *p;

        if (strcmp(name,(*p)->name) < 0)
            *p = (*p)->pGauche;
        else
            *p = (*p)->pDroit;
    }

}

void getName(char name[])
{
    printf("What name do you want to add\n");
    scanf("%s",name);
    fflush(stdin);

}

void copy(Node **root, Node *savep, char name[])
{
    Node *newp = (Node *) malloc(sizeof(Node*));
    newp->pDroit = NULL;
    newp->pGauche = NULL;

    strcpy(newp->name,name);
    printf("%s",newp->name);


    if (*root == NULL)
        *root = newp;
    else
    {
        if (strcmp(name,savep->name) < 0) 
            savep->pGauche = newp;
        else
            savep->pDroit = newp;
    }
    free(newp);
}

void print(Node ** root)
{
    Node *p = *root;
    inOrder(p);
}

void inOrder(Node *p)
{
    if (p != NULL)
    {
        inOrder(p->pGauche);
        printf("%s\n",p->name);
        inOrder(p->pDroit);
    }
}

我知道有一些非常奇怪的函数和无用的函数,但这只是一个稍微大一点的学校项目的“测试”,所以它会及时变得有用,现在我只想让二叉树工作!

所以基本上问题是我在输入第二个名称后得到“访问冲突读取位置”......我猜是在执行 strcmp 时,但我真的不确定:/

如果有人可以帮助我运行此程序,我真的很高兴 :)

【问题讨论】:

  • 您应该尝试在调试器中运行您的代码,以更好地了解代码崩溃的原因。

标签: c binary-search-tree


【解决方案1】:

有几件事可以帮助您入门。我没有深入研究它,因此您可能需要继续深入研究更多问题,但修复这些问题只是为了让您开始:

search()的这段代码中:

    while ((p == NULL) && (strcmp((*p)->name,name) != 0))

p 参数永远不会为 NULL。因此,永远不会进入 while 循环。这意味着savep 不会被设置为任何值,并且当您在add() 函数中调用copy() 时为NULL。然后copy() 函数取消引用无效的指针引用,这导致了您观察到的问题。

您实际上想测试*p 是否为NOT NULL。这允许您合法地取消引用它。

    while ((*p != NULL) && (strcmp((*p)->name,name) != 0))

其次,正如hmjd 所指出的,您没有为copy() 内的节点分配足够的内存。

    Node *newp = (Node *) malloc(sizeof(Node*));

您只为一个指针分配了足够的内存,而不是为整个节点分配了足够的内存。此外,在 C 中编码时,您不应强制转换 malloc() 的返回值(它会隐藏一个在最坏情况下可能导致崩溃的错误)。

    Node *newp = malloc(sizeof(Node));

第三,你需要保留你为你的节点分配的内存,而不是在copy()末尾插入后立即释放它们:

    // I need this memory for my tree!
    //free(newp);

如果您像以前一样调用free(),那么您的tree 将指向已释放的内存,访问它们会导致未定义的行为。

一件小事:你不应该做fflush(stdin),因为fflush() 仅用于输出流。

【讨论】:

  • 还有一份给你。正如您所发现的,代码中有许多错误。可能还有其他人,但 OP 至少可以修复列出的那些并希望能学到一些东西。使他/她能够修复答案中未提及的其他错误。
  • 非常感谢你们两个,这确实很有帮助,帮助我从错误中吸取教训 :D 现在一切都很顺利!
【解决方案2】:

这是不正确的:

while ((p == NULL) && (strcmp((*p)->name,name) != 0))

并且会导致 NULL 指针被取消引用,这是未定义的行为。改为:

while (*p && strcmp((*p)->name,name) != 0)

这是不正确的:

Node *newp = (Node *) malloc(sizeof(Node*));

因为它只为Node* 分配了足够的空间,当它需要分配Node 时。改为:

Node *newp = malloc(sizeof(*newp));

并且不要free() 它与稍后需要的功能相同。 free()ing Node 表示列表具有 dangling pointers 并且取消引用一个是未定义的行为,并且可能是访问冲突的原因。


注意:

fflush(stdin);

是未定义的行为。来自fflush()参考页面:

使输出文件流与文件的实际内容同步。 如果给定的流是输入类型,那么函数的行为是未定义的。

【讨论】:

  • 您对提问者问题的原因分析不完整。
  • @user315052,好的,但至少会有所帮助。
  • 是的,这就是我为你 +1 的原因。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多