C 向函数传递字符串变量时出现分段错误,但传递字符串常量(如“0”)时出现分段错误;“你好”;

C 向函数传递字符串变量时出现分段错误,但传递字符串常量(如“0”)时出现分段错误;“你好”;,c,segmentation-fault,C,Segmentation Fault,我正在编辑一个trie程序,将我自己的字符串输入trie。当我传递像“hello”这样的常量时,不会出现分段错误,但当我传递字符串变量时,它会出现分段错误(核心转储)。 这就是功能:- void insert(struct Trie *head, char* str)//FUNCTION CONCERNED WITH SEGMENTATION FAULT POSSIBLY OTHERS { // start from root node struct Trie* curr = h

我正在编辑一个trie程序,将我自己的字符串输入trie。当我传递像“hello”这样的常量时,不会出现分段错误,但当我传递字符串变量时,它会出现分段错误(核心转储)。 这就是功能:-

void insert(struct Trie *head, char* str)//FUNCTION CONCERNED WITH SEGMENTATION FAULT POSSIBLY OTHERS
{
    // start from root node
    struct Trie* curr = head;
    while (*str)
    {
        // create a new node if path doesn't exists
        if (curr->character[*str - 'a'] == NULL)
            curr->character[*str - 'a'] = getNewTrieNode();

        // go to next node
        curr = curr->character[*str - 'a'];

        // move to next character
        str++;
    }
考虑

struct Trie *head=(struct Trie*)malloc(sizeof(struct Trie));
insert(head,"hello");
这很好 但是如果我给一个字符串(输入)赋值并传递它

char str[100];
scanf("%s",str);
insert(head,str);
这会产生seg故障。(插入函数,而不是scanf) 我不擅长调试segfaults,因此我希望得到一些帮助,了解为什么会出现这种情况。我该如何纠正它 下面的完整代码供参考(完全向下滚动至主功能)

#包括
#包括
#包括
#包括
//定义字符大小
#定义字符大小26
//Trie节点
结构Trie
{
int isLeaf;//当节点是叶节点时为1
结构Trie*字符[CHAR_SIZE];
};
//函数返回一个新的Trie节点
结构Trie*getNewTrieNode()
{
struct-Trie*node=(struct-Trie*)malloc(sizeof(struct-Trie));
节点->isLeaf=0;
对于(int i=0;i字符[i]=NULL;
返回节点;
}
//在Trie中插入字符串的迭代函数
void insert(struct Trie*head,char*str)//与分段错误相关的函数
{
//从根节点开始
结构Trie*curr=头部;
while(*str)
{
//如果路径不存在,请创建新节点
if(curr->character[*str-'a']==NULL)
curr->character[*str-'a']=getNewTrieNode();
//转到下一个节点
curr=curr->character[*str-'a'];
//移动到下一个角色
str++;
}
//将当前节点标记为叶
curr->isLeaf=1;
}
//用于在Trie中搜索字符串的迭代函数。它返回1
//如果在Trie中找到字符串,则返回0
int搜索(struct Trie*head,char*str)
{
//如果Trie为空,则返回0
if(head==NULL)
返回0;
结构Trie*curr=头部;
while(*str)
{
//转到下一个节点
curr=curr->character[*str-'a'];
//如果字符串无效(到达Trie中路径的末尾)
if(curr==NULL)
返回0;
//移动到下一个角色
str++;
}
//如果当前节点是叶,并且我们已经到达
//字符串末尾,返回1
返回当前->isLeaf;
}
//如果给定节点有任何子节点,则返回1
int haveChildren(结构Trie*curr)
{
对于(int i=0;i字符[i])
返回1;//找到子项
返回0;
}
//递归函数删除Trie中的字符串
int删除(结构Trie**curr,char*str)
{
//如果Trie为空,则返回
如果(*curr==NULL)
返回0;
//如果我们还没有到达绳子的末端
如果(*str)
{
//针对中对应于下一个字符的节点重复出现
//字符串,如果返回1,则删除当前节点
//(如果是非叶子)
如果(*curr!=NULL&&(*curr)->字符[*str-'a']!=NULL&&
删除(&((*curr)->字符[*str-'a']),str+1)&&
(*curr)->isLeaf==0)
{
如果(!有子女(*curr))
{
免费(*货币);
(*curr)=空;
返回1;
}
否则{
返回0;
}
}
}
//如果我们已经到了绳子的尽头
如果(*str=='\0'&(*curr)->isLeaf)
{
//如果当前节点是叶节点且没有任何子节点
如果(!有子女(*curr))
{
free(*curr);//删除当前节点
(*curr)=空;
返回1;//删除非叶父节点
}
//如果当前节点是叶节点且具有子节点
其他的
{
//将当前节点标记为非叶节点(不删除)
(*curr)->isLeaf=0;
返回0;//不删除其父节点
}
}
返回0;
}
//Trie在C中的实现&插入、搜索和删除
int main()
{
struct Trie*head=getNewTrieNode();
插入(标题“你好”);
printf(“%d”,search(head,“hello”);//打印1
插入(标题为“helloworld”);
printf(“%d”,搜索(head,“helloworld”);//打印1
printf(“%d”,search(head,“helll”);//打印0(不存在)
插入(标题“地狱”);
printf(“%d”,search(head,“hell”);//打印1
插入(标题“h”);
printf(“%d\n”,search(head,“h”);//打印1+换行符
删除(&head,“hello”);
printf(“%d”,search(head,“hello”);//打印0(hello已删除)
printf(“%d”,搜索(head,“helloworld”);//打印1
printf(“%d\n”,search(head,“hell”);//打印1+换行符
删除(&标题“h”);
printf(“%d”,search(head,h”);//打印0(h已删除)
printf(“%d”,search(head,“hell”);//打印1
printf(“%d\n”,search(head,“helloworld”);//打印1+换行
删除(&head,“helloworld”);
printf(“%d”,搜索(head,“helloworld”);//打印0
printf(“%d”,search(head,“hell”);//打印1
删除(&head,“hell”);
printf(“%d\n”,search(head,“hell”);//打印0+换行符
if(head==NULL)
printf(“Trie empty!!\n”);//Trie现在为空
printf(“%d”,search(head,“hell”);//打印0
//这里是分段错误问题的起点
char-str[100];
int i=0;
scanf(“%s”,str);

对于(i=0;i当您从trie中删除最后一个字符串时,您将删除它的所有祖先,包括根节点。这将使
head
NULL。然后将
head
传递给
insert
,从而取消对它的引用

您可以安排不删除根节点(并更改检测空trie的方式),但解决此问题的另一种方法是使
insert
根节点成为中间节点之外的根节点

void insert(struct Trie **curr, const char* str) {
    while (1) {
        if (!*curr)
            *curr = getNewTrieNode();

        if (!*str)
            break;

        curr = &( curr->character[*str - 'a'] );
        ++str;
    }

    (*curr)->isLeaf = 1;
}
这是
void insert(struct Trie **curr, const char* str) {
    while (1) {
        if (!*curr)
            *curr = getNewTrieNode();

        if (!*str)
            break;

        curr = &( curr->character[*str - 'a'] );
        ++str;
    }

    (*curr)->isLeaf = 1;
}
struct Trie* head = getNewTrieNode();
struct Trie* head = NULL;