简体   繁体   English

使用指针在链表中进行结构构造时出现C分段错误

[英]C segmentation fault when using pointer to structure in a linked list

I write a very basic linked list in C supporting only two operations - insert of a node to the top of the list and iterate over the list in order to print the value of each node. 我用C语言编写了一个非常基本的链接列表,仅支持两种操作-在列表顶部插入一个节点,然后遍历该列表以打印每个节点的值。 The problem I am facing is that I have a segmentation fault when executing. 我面临的问题是执行时出现分段错误。 Here is my code: 这是我的代码:

#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 = %d\n", 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;
}

I know this question has been asked many times on stackoverflow and yet I still can't figure out why my code does not work as expected. 我知道这个问题已经在stackoverflow上被问过很多次了,但是我仍然不知道为什么我的代码不能按预期工作。 Can you please explain to me where is the problem and how can I fix it? 您能否向我解释问题出在哪里,我该如何解决? Thank you 谢谢

This: 这个:

node = NULL;

doesn't look so good in the createNode() function. createNode()函数中看起来不太好。 In fact, that entire function doesn't look so good. 实际上,整个功能看起来并不那么好。 It should be something like this: 应该是这样的:

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

It really shouldn't have been allocating more than one node, that's not sane. 实际上不应该分配多个节点,这不是理智的做法。

There are two main issues. 有两个主要问题。 First createNode : 第一个createNode

You allocate space for a struct linkedList and assign it to node , which is good. 您为struct linkedList分配空间,并将其分配给node ,这很好。 But then you do the same for node->next . 但是,然后对node->next执行相同的操作。 So you're actually creating two nodes, but then you set node->next to NULL ,loosing the reference to the second bit of memory you allocated, creating a memory leak. 因此,您实际上是在创建两个节点,但随后将node->next设置为NULL,失去对分配的第二个内存的引用,从而导致内存泄漏。 The same happens when you do the same for node . 当对node执行相同操作时,也会发生相同的情况。 The end result is that you always return NULL for your new node. 最终结果是您始终为新节点返回NULL。 Also, you don't assign value to anything. 此外,您不分配value到任何东西。

Just do the first allocation, assign value to data , and initialize next to NULL: 只需进行第一次分配,将value分配给data ,然后在NULL next初始化:

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

The next issue is in iterate : 下一个问题是iterate

while(top->next != NULL)

This causes the iteration to stop when the current node is the last one, so you don't print the last node. 当当前节点是最后一个节点时,这将导致迭代停止,因此您不会打印最后一个节点。 Also, as a result of how createNode was originally implemented, your root pointer is NULL, so you end up dereferencing a NULL pointer, which causes a core dump. 另外,由于createNode最初是如何实现的,因此您的root指针为NULL,因此最终会取消引用NULL指针,这将导致核心转储。

You want to test if top is NULL instead: 您想测试top是否为NULL:

while(top != NULL)

A third issue is cleanup. 第三个问题是清理。 You need to define a function to free the memory you allocated before your program exits. 您需要定义一个函数,以在程序退出之前free分配的内存。 You can do that like this: 您可以这样做:

void cleanup(struct linkedList *top)
{
    struct linkedList *temp;

    while (top != NULL) {
        temp = top;
        top = top->next;
        free(temp);
     }
}

If you like to create a node you only have to allocate mamory for one node. 如果您想创建一个节点,则只需为一个节点分配内存。 Adapt your code like this: 像这样修改您的代码:

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

Apart from this you have to change the termination condition of the while loop in your function iterate : 除此之外,您还必须在函数iterate更改while循环的终止条件:

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

And you can simplify your function insertTop : 您可以简化函数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;
}

Dont't forget to free your list at the end of main : 不要忘记在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; 
}

Apart from this you can combine createNode and insertTop to one function createTop : 除此之外,您可以将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;
}

You have quite a few problems there.. 你那里有很多问题。

In the function createNode() you are allocatting memory to node and then throwing it away by doing node = NULL . 在函数createNode()您将内存分配给node ,然后通过执行node = NULL丢弃它。

Loose those statements, as they create a memory leak. 松开这些语句,因为它们会导致内存泄漏。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM