【问题标题】:Function call for second time causing segementation fault第二次调用函数导致分段错误
【发布时间】:2019-08-18 06:17:13
【问题描述】:

我一直在尝试执行以下 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

【问题讨论】:

  • 我可以看到这个输出 /ay/by/by /ay/by/ /by /ay/by/by /ay/by/ /by 没有评论第 2 行。你期待什么?
  • 您是否尝试过使用像 GDB 这样的调试器?它可以帮助您确定程序在哪一行崩溃。
  • 由于两个函数调用是相同的,我应该得到与你得到的一样的输出。但相反,我得到了“分段错误”。 @Achal
  • 我正在使用 GCC 编译器,您使用的是哪一个? @Achal?
  • @kinder_shah 我使用 GDB 来尝试获取导致问题的特定语句。但它没有显示特定的行。它只给出输出以及 SIGSEGV 错误。

标签: c pointers segmentation-fault


【解决方案1】:

无论您期望什么输出,都很少有需要纠正的地方。

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

 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

【讨论】:

  • 成功了。只需要提供“struct Node”而不是“struct Node *”。谢谢。
【解决方案2】:

在函数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;
}

【讨论】:

    猜你喜欢
    • 2018-05-04
    • 1970-01-01
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-26
    • 1970-01-01
    • 2015-11-28
    相关资源
    最近更新 更多