【问题标题】:Segmentation Fault 11 with ANSI C Linked ListANSI C 链表的分段错误 11
【发布时间】:2014-05-28 07:25:42
【问题描述】:

更新了一些新的细节:

有趣的是,如果我不使用没有段错误:node->next = NULL。我可以很好地创建节点,但似乎在将初始列表头设置为我的新节点以及取消引用->下一个方面存在问题。

【问题讨论】:

    标签: c linked-list segmentation-fault


    【解决方案1】:

    请注意,如果没有结构定义,我们很难知道哪里出了问题...

    您在测试 malloc() 是否失败之前使用分配的指针时遇到问题。虽然目前这可能不是罪魁祸首。

    struct node *head = (struct node*)malloc(sizeof(struct ftt_node));
    foodList->head = head;      // <<<---- here using the pointer NULL or not
    head->next = NULL;
    rest->foods = foodList;
    
    if (NULL == rest->foods) {       // <<<---- testing here if malloc() failed
        printf("List creation failed");
        return FALSE;
    }
    

    顺便说一句,head 指针也有同样的问题。

    然后在 add_node 中执行此操作,而 newNode 从未分配...所以可能是垃圾!

    struct node *newNode;
    newNode->data = newFood;
    

    您可能想分配 newNode 并使用 curr 查找最后一个现有节点。

    类似这样的:

    void add_node(POS * POS, struct food * newFood)
    {
        struct node *newNode;
    
        struct node *newNode = (struct node*)malloc(sizeof(struct node));
        newNode->data = newFood;
    
        curr = POS->foods->head;
    
        while (curr != NULL)
        {
            curr = curr->next;
        }
    
        curr->next = newNode;
        newNode->next = NULL;
    }
    

    话虽如此,我强烈建议您创建一个包含处理列表的函数的基本列表对象,然后使用该列表启动您的节点,而不是这样写。

    附带说明:您不应该在 add_node() 中命名变量 POS。这是不好的做法,因为它会影响您的变量类型。

    只是想知道,为什么不使用 C++?至少不需要对 NULL 进行测试,因为如果无法分配内存,new 会抛出......对于列表,你有 std::list,尽管在你的情况下 std::vector 可能会更好,所以你可以通过你的数组具有非常简单的 for() 的节点。

    【讨论】:

    • 我已经编辑了上面的代码以反映这里推荐的一些更改。我还将重构变量名称。 (而且我必须使用 ANSI C!)
    【解决方案2】:

    你在 add_node 中的 newNode 变量是单元化的,所以它可以指向内存中的任何地方,当你试图在第二行取消引用它时,这可能是导致段错误的原因。此外,您分配了一个新的 struct 节点结构,但立即覆盖了它的地址。所以你的前几行应该这样重写:

    struct node *newNode = (struct node*)malloc(sizeof(struct node));
    newNode->data = newFood;
    struct node *curr = POS->foods->head;
    

    【讨论】:

    • 我想我已经解决了这些问题,尽管段错误仍然存​​在。
    【解决方案3】:

    add_node() 函数永远不会修改 pos-&gt;foods-&gt;head。它也从不初始化new_node,因此在不触发未定义行为的情况下无法取消引用指针。

    因此,列表永远不会因空而增长。

    【讨论】:

    • 我为 create_node 创建了一个单独的函数,只是为了稍微清理一下代码,是的,你说得对,永远不要修改初始头部。我很确定我已经解决了这个问题,但我已经更准确地阐述了(我认为)导致段错误的原因。
    猜你喜欢
    • 2015-12-31
    • 1970-01-01
    • 2012-10-10
    • 2014-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多