在链表中使用指向结构的指针时出现 C 分段错误



我用 C 编写了一个非常基本的链表,只支持两个操作 - 在列表顶部插入一个节点并迭代列表以打印每个节点的值。我面临的问题是我在执行时遇到分段错误。这是我的代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct linkedList
{
    int data;
    struct linkedList *next;
};
struct linkedList* createNode(int value)
{
    struct linkedList *node;
    node = malloc(sizeof(struct linkedList));
    node->next = malloc(sizeof(struct linkedList));
    node->next = NULL;
    node = NULL;
    return node;
}
//insert a node at the top of the linked list
struct linkedList* insertTop(struct linkedList* top,struct linkedList* node)
{
    if(top == NULL)//the element we insert is the 1st element for the linked list
    {
        node->next = NULL;
        //the first element points to NULL since it has no successors
    }
    else//there is already an element in the list
    {
        node->next = top;
    }
    return node;
}
void iterate(struct linkedList* top)
{
    while(top->next != NULL)
    {
        printf("Data = %dn", top->data);
        top = top->next;
    }
}
int main()
{
    struct linkedList *a,*b,*c,*root;
    a = createNode(2);
    b = createNode(10);
    c = createNode(23);
    root = insertTop(NULL,a);//these 3 lines provoke a segmentation fault
    root = insertTop(root,b);
    root = insertTop(root,c);
    iterate(root);//the result I expect here is 23,10,2 
    return 0;
}

我知道这个问题已经在stackoverflow上被问了很多次,但我仍然无法弄清楚为什么我的代码不能按预期工作。你能向我解释问题在哪里以及如何解决它吗?谢谢

有两个主要问题。 第一createNode

您为struct linkedList分配空间并将其分配给node,这很好。 但是你对node->next做同样的事情. 所以你实际上是在创建两个节点,但随后你node->next设置为 NULL,丢失对你分配的第二位内存的引用,从而产生内存泄漏。 当您对node执行相同操作时,也会发生同样的情况。 最终结果是始终为新节点返回 NULL。 此外,您不会value分配给任何内容。

只需执行第一次分配,将value分配给data,然后将next初始化为 NULL:

struct linkedList* createNode(int value)
{
    struct linkedList *node;
    node = malloc(sizeof(struct linkedList));
    node->data = value;
    node->next = NULL;
    return node;
}

下一期是iterate

while(top->next != NULL)

这会导致迭代在当前节点是最后一个节点时停止,因此您不会打印最后一个节点。 此外,由于最初实现createNode的方式,root指针为 NULL,因此最终会取消引用 NULL 指针,从而导致核心转储。

您想改为测试top是否为 NULL:

while(top != NULL)

第三个问题是清理。 您需要定义一个函数来free程序退出之前分配的内存。 你可以这样做:

void cleanup(struct linkedList *top)
{
    struct linkedList *temp;
    while (top != NULL) {
        temp = top;
        top = top->next;
        free(temp);
     }
}

这个:

node = NULL;

createNode()函数中看起来不太好。事实上,整个功能看起来并不那么好。它应该是这样的:

struct linkedList* createNode(int value)
{
    struct linkedList *node = malloc(sizeof *node);
    node->next = NULL;
    node->data = value;
    return node;
}

真的不应该分配多个节点,这是不理智的。

如果你想创建一个节点,你只需要为一个节点分配mamory。像这样调整你的代码:

struct linkedList* createNode(int value)
{
    struct linkedList *node = malloc(sizeof(struct linkedList));
    node->next = NULL;
    node->data = value;
    return node;
}

除此之外,您必须更改函数中while循环的终止条件iterate

void iterate( struct linkedList *top )
{
    while( top != NULL) // if to is not NULL you can print its data
        // ^^^ 
    {
        printf("Data = %dn", top->data);
        top = top->next;
    } 
}

您可以简化您的功能insertTop

struct linkedList* insertTop(struct linkedList* top,struct linkedList* node)
{
    if( node == NULL ) // test if node is not NULL
        return top;
    node->next = top;  // successor of new node is top (top possibly is NULL)
    return node;
}

不要忘记在main末尾free您的列表:

int main()
{
    struct linkedList *root = NULL;
    root = insertTop( root, createNode(2) );
    root = insertTop( root, createNode(10) );
    root = insertTop( root, createNode(23) );
    iterate(root);
    while ( root != NULL )
    {
        struct linkedList *temp = root;
        root = root->next; 
        free( temp );
    }
    return 0; 
}

除此之外,您还可以将createNodeinsertTop组合到一个功能createTop

struct linkedList* createTop( struct linkedList* top, int value )
{
    struct linkedList *node = malloc(sizeof(struct linkedList));
    node->next = top;
    node->data = value;
    return node;
}

你那里有很多问题。

在函数createNode()中,您将内存分配给node,然后通过执行node = NULL将其丢弃。

松开这些语句,因为它们会产生内存泄漏。

struct linkedList* createNode(int value)
{
    struct linkedList *node;
    node = malloc(sizeof(struct linkedList));
    node->data = value;
    node->next = NULL;
    return node;
}

相关内容

  • 没有找到相关文章

最新更新