此代码在Windows上提供了未定义的行为,但在Linux上运行正常

时间:2013-09-11 16:45:07

标签: c list linked-list mingw

我正在尝试用C编写一个小的双链表程序,但由于某种原因它给了我第一个元素的未定义行为。我希望它在开头有一个空单元格,它连接第一个和最后一个元素。所以它是这样的:... <-> Second Last <-> Last <-> Empty Cell <-> First <-> Second <->...

第一个元素是随机值,但下一个元素有效。例如,如果我的输入文件是1 2 3 4 5,则输出将是<undefined> 2 3 4 5,其中undefined可以是C希望给我的任何数字。

奇怪的是它在调试模式下也能完美运行(使用MinGW Developer Studio,因为我从学校习惯了)。它在Linux下运行良好(使用gcc进行编译)。

这是代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct Nod {
struct Nod *next, *ant;
int x;
} Nod_t, *List_t, **AList_t;

void PrintList (List_t sant){
List_t lista = sant->next;
while(lista != sant){
    printf("%i ", lista->x);
    lista = lista->next;
}
}

List_t PopulateList(char* fis){

List_t lista, sant;
int nr;
FILE *f = fopen(fis, "rt");

sant = (List_t)malloc(sizeof(List_t));
sant->next = sant->ant = NULL;
lista = sant;
//First node

while(!feof(f)){
    fscanf(f, "%i", &nr);
    lista->next = (List_t)malloc(sizeof(List_t));
    lista->next->x = nr;
    lista->next->ant = lista;
    lista = lista->next;
}

sant->ant = lista;
lista->next = sant;

return sant;

}

int main (){

List_t lista1;
lista1 = PopulateList("1.txt");
PrintList(lista1);
return 0;
}

这里更好的缩进:http://pastebin.com/NVQqaYHK

2 个答案:

答案 0 :(得分:1)

尝试从

更改mallocs
sant = (List_t)malloc(sizeof(List_t));

sant = malloc(sizeof(Nod_t));

sant = malloc(sizeof(List_t));返回指向区域大小的指针。

sant = malloc(sizeof(Nod_t));返回一个指向Nod_t大小区域的指针。

顺便说一句,这是一个风格问题,但你的类型别名令人困惑,可能导致你在mallocs中的拼写错误。我建议只使用Nod_t类型并删除List_t和AList_t。请考虑以下声明:

List_t foo; // is this a pointer or a struct? Can't tell from the decl, need to know the typedef.
Nod_t *foo; // obviously a pointer

另见Zack的建议,特别是有关feof()问题的建议。

答案 1 :(得分:1)

错误在这里:

sant = (List_t)malloc(sizeof(List_t));
sant->next = sant->ant = NULL;
lista = sant;

您没有初始化sant->x,因此您在列表中有一个条目(之前包含文件中实际数据的所有条目),并且未初始化x。< / p>

当您稍后打印x all 列表中的条目时,会触发未定义的行为(在Linux和Windows上都要清楚;未定义的行为包括可能性打印的值总是为零。)

您应该在显示的代码之后立即重新构建循环,这样您就不会在读取文件中的第一行之前分配列表中的第一个条目,并且您没有此初始列表条目具有未初始化的价值。

你还需要Charlie Burns提到的修正错误。