【问题标题】:C linked list: Segmentation fault on Windows, works on MacC链表:Windows上的分段错误,适用于Mac
【发布时间】:2016-02-08 18:51:40
【问题描述】:

我正在尝试通过 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,尽管它应该指向 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::blocks)

Example on IDEone Example on Codepad

【问题讨论】:

  • 在 XCode 中调试不会显示任何错误,valgrind 也不会。但是运行编译后的二进制文件会导致分段错误
  • 通常,如果您的程序在一台计算机上出现段错误并且似乎在另一台计算机上“工作”,那么它会表现出“未定义的行为”。谷歌“未定义行为 C”以了解更多信息。

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


【解决方案1】:

对于列表的第一个元素,您必须使用NULL 初始化ele->next,否则对于列表的最后一个元素,您将访问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;
}

确保使用NULL 初始化head-&gt;fronthead-&gt;end

【讨论】:

  • 谢谢,问题似乎在于我忘记初始化 head->front 和 head->end 为 NULL。
【解决方案2】:

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

【讨论】:

  • 非常感谢您提供的信息。我不知道这个事实。
  • calloc 将清除该区域的所有位,这不一定与 空指针 (或0.0,顺便说一句)相同。更好的是显式设置指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-18
  • 2013-10-31
  • 2015-12-31
相关资源
最近更新 更多