第二次函数调用导致分段故障

时间:2019-08-18 06:17:13

标签: c pointers segmentation-fault

我一直在尝试执行以下C程序。该程序执行时没有任何错误,但是会发出“ Segmentation Fault”错误消息。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Node
{
    char str[100];
    struct Node *children[100];
    int numc;
    int isd;
};

void _strsearch(struct Node *node, char *name, char *res)
{
    int i = 0;
    char cpy[200];
    strcpy(cpy, res);
    if (strcmp(node->str, "") != 0)
        strcat(cpy, "/");
    strcat(cpy, node->str);
    for (; i < node->numc; i++)
    {
        _strsearch(node->children[i], name, cpy);
        strcpy(cpy, res);
        if (strcmp(node->str, "") != 0)
            strcat(cpy, "/");
        strcat(cpy, node->str);
    }
    if (strcmp(name, node->str) == 0)
    {
        strcat(res, "/");
        strcat(res, node->str);
        if (node->isd)
            strcat(res, "/");
        printf(" %s ", res);
    }
}

void strsearch(struct Node *tree, char *name)
{
    char path[200];
    strcpy(path, tree->str);
    _strsearch(tree, name, path);
}

struct Node *create_root()
{
    struct Node *t = (struct Node *)malloc(sizeof(struct Node));
    strcpy(t->str, "");
    t->numc = 0;
    t->isd = 0;
    return t;
}

struct Node *add_node(struct Node *tree, char *name, int isd)
{
    struct Node *t = (struct Node *)malloc(sizeof(struct Node *));
    strcpy(t->str, name);
    t->numc = 0;
    t->isd = isd;
    tree->children[tree->numc] = t;
    tree->numc += 1;
    return tree;
}

struct Node* del_node(struct Node *tree, char *name)
{
    int i, j;
    for (i = 0; i < tree->numc; i++)
    {
        if (strcmp(tree->children[i]->str, name) == 0)
        {
            for (j = i; j < tree->numc - 1; j++)
                tree->children[j] = tree->children[j + 1];

            tree->numc -= 1;
            i -= 1;
        }
    }
    return tree;
}

int main()
{
    struct Node *tree;
    struct Node *t;
    tree = create_root();
    tree = add_node(tree, "ay", 0);
    tree = add_node(tree, "by", 0);
    t = tree->children[0];
    t = add_node(t, "by", 1);
    t = t->children[0];
    t = add_node(t, "by", 0);
    t = add_node(t, "gy", 0);
    strsearch(tree, "by"); // line 1
    strsearch(tree, "by"); // line 2
    return 0;
}

当我完全注释掉“第2行”时,该程序会提供所需的输出。 为什么会这样?两个函数调用的参数相同。并且(根据我)函数_strsearch()不会更改参数的任何值。有人可以帮助我确定这种行为的真正原因吗?

注释“第2行”时的输出(正确):

 /ay/by/by  /ay/by/  /by

2 个答案:

答案 0 :(得分:1)

无论您期望什么输出,都很少需要纠正的事情。

首先在char缓冲区下面初始化。例如

 char path[200] = {0}; /* zerod whole buffer */
 char cpy[200] = {0};

第二,在add_node()函数中,内存分配应为

struct Node *t = (struct Node *)malloc(sizeof(struct Node)); /* number of bytes should be equal to size of struct Node */

代替

struct Node *t = (struct Node *)malloc(sizeof(struct Node *));

并检查malloc()的返回值。例如

struct Node *t = (struct Node *)malloc(sizeof(struct Node));
if(t == NULL) {
  fprintf(stderr, "malloc() failed\n");
  exit(1);
}

这里是live demo

答案 1 :(得分:1)

在功能add_node上,您为指针而不是整个节点分配内存。 您的代码:

struct Node *t = (struct Node *)malloc(sizeof(struct Node *));

正确的代码:

struct Node *t = (struct Node *)malloc(sizeof(struct Node));

和完整的工作代码(使用MS Visual Studio 2019进行编译和测试):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Node
{
    char str[100];
    struct Node* children[100];
    int numc;
    int isd;
};

void _strsearch(struct Node* node, const char* name, char* res)
{
    int i = 0;
    char cpy[200];
    strcpy(cpy, res);
    if (strcmp(node->str, "") != 0)
        strcat(cpy, "/");
    strcat(cpy, node->str);
    for (; i < node->numc; i++)
    {
        _strsearch(node->children[i], name, cpy);
        strcpy(cpy, res);
        if (strcmp(node->str, "") != 0)
            strcat(cpy, "/");
        strcat(cpy, node->str);
    }
    if (strcmp(name, node->str) == 0)
    {
        strcat(res, "/");
        strcat(res, node->str);
        if (node->isd)
            strcat(res, "/");
        printf(" %s ", res);
    }
}

void strsearch(struct Node* tree, const char* name)
{
    char path[200];
    strcpy(path, tree->str);
    _strsearch(tree, name, path);
}

struct Node* create_root()
{
    struct Node* t = (struct Node*)malloc(sizeof(struct Node));
    strcpy(t->str, "");
    t->numc = 0;
    t->isd = 0;
    return t;
}

struct Node* add_node(struct Node* tree, const char* const name, int isd)
{
    struct Node* t = (struct Node*)malloc(sizeof(struct Node));
    strcpy(t->str, name);
    t->numc = 0;
    t->isd = isd;
    tree->children[tree->numc] = t;
    tree->numc += 1;
    return tree;
}

struct Node* del_node(struct Node* tree, const char* const name)
{
    int i, j;
    for (i = 0; i < tree->numc; i++)
    {
        if (strcmp(tree->children[i]->str, name) == 0)
        {
            for (j = i; j < tree->numc - 1; j++)
                tree->children[j] = tree->children[j + 1];

            tree->numc -= 1;
            i -= 1;
        }
    }
    return tree;
}

int main()
{
    struct Node* tree;
    struct Node* t;
    tree = create_root();
    tree = add_node(tree, "ay", 0);
    tree = add_node(tree, "by", 0);
    t = tree->children[0];
    t = add_node(t, "by", 1);
    t = t->children[0];
    t = add_node(t, "by", 0);
    t = add_node(t, "gy", 0);
    strsearch(tree, "by"); // line 1
    strsearch(tree, "by"); // line 2
    return 0;
}