C链表:Windows上的分段错误,适用于Mac

时间:2016-02-08 18:51:40

标签: c xcode list linked-list segmentation-fault

我试图通过C中的链接列表。

列表项定义为

struct list_element {
  struct list_element *next;
  int value;
};

列表头定义为

struct list_head {
  struct list_element *front;
  struct list_element *end;
};

我试图打印这样的项目

void printList(struct list_head* head) {
    if(head == NULL|| head->front == NULL) {
        printf("List is empty \n");
        return 0;
    }

    struct list_element* elm = head-> front;
    int numberOfElements = 0;

    while(elm != NULL) {
        printf("%i", elm -> value);
        printf(" ");
        elm = elm -> next;
    }
    printf("\n");
}

这在我的Mac上在XCode和https://ideone.com上运行良好,但在Windows和http://codepad.org上会导致"分段错误"。好像是

while(elm != NULL) {
    printf("%i", elm -> value);
    printf(" ");
    elm = elm -> next;
}

导致一些问题。似乎elm并没有指向最后一项的NULL,即使它应该。

我正在添加像这样的项目

struct list_element* list_push(struct list_head* head) {

    //List head is null
    if(!head) {
        return NULL;
    }

    //Initialize list element

    struct list_element* elm = malloc(sizeof(struct list_element));

    if(elm == NULL) {
        //Couldn't alloc memory
        return NULL;
    }

    if(head->front) {
        head->front = elm;
        head->end = elm;
    } else {
        //List head is not null, set next elm to point to current elm
        elm -> next = head -> front;
        head->front = elm;

    }

    return elm;
}

我真的很困惑为什么相同的代码在某些地方可以使用,但在其他地方则不然。 (它适用于IDEone和XCode,它不能在Windows上使用相同的代码在Codepad和Code :: block上工作)

Example on IDEone Example on Codepad

2 个答案:

答案 0 :(得分:3)

对于列表的第一个元素,您必须使用ele->next初始化NULL,否则您将在elm = elm->next中访问未初始化的内存以获取列表的最后一个元素。除此之外,您必须将if(head->front)更改为if ( head->front == NULL )。像这样调整你的代码:

struct list_element* list_push(struct list_head* head) {

    if ( head == NULL )
        return NULL;

    struct list_element* elm = malloc(sizeof(struct list_element));
    if ( elm == NULL)
        return NULL;

    if ( head->front == NULL)  // <--------------
    {
        elm->next = NULL;     // <---------------
        head->front = elm;
        head->end = elm;
    }
    else
    {    
        elm->next   = head->front;
        head->front = elm;
    }
    return elm;
}

请务必使用head->front初始化head->end NULL

答案 1 :(得分:2)

问题是malloc没有为你分配给它的内存归零。您可以手动将next指针设置为NULL,也可以使用calloc分配内存,这将为您归零。它在某些环境中运行而不是在其他环境中运行的原因是,它在某些情况下会击中已经用零写入的内存,或者出于安全原因某些操作系统将为您清零内存。