c/c++语言开发共享为什么这个C链表程序会出现“分段错误”?

第一个函数读取一个包含一堆’char’的文件,并将它们放在一个链表中。 它无法正常工作:(。

#include  #include  struct list { char val; struct list* next; }; typedef struct list element; int lcreate(char* fname, element* list); int ldelete(element* list); int linsert(char a, char b, element* list); int lremove(char a, element* list); int lsave(char* fname, element* list); int lcreate(char* fname, element* list) { element* elem = list; char c = 0; FILE * file = NULL; file = fopen(fname, "r"); while ((c = getc(file)) != EOF) { if(list == NULL) { list = (element*)malloc(sizeof(element)); if(list == NULL) { return 0; } list->val = c; } else { elem->next=(element*)malloc(sizeof(element)); elem = elem->next; elem-> val = c; } } fclose(file); elem->next = NULL; return 1; } int main(void) { int i = 0; element * list = NULL; lcreate("list.txt", list); for(i = 0; ival); list = list->next; } return 0; } 

修复了’file’为空的问题。

    一个明显的问题就在这里:

     FILE * file = NULL; fopen(fname, "r"); 

    为了使fopen能够完成很多工作,你需要将fopen的结果赋给你的FILE *

     file = fopen(fname, "r"); 

    编辑:由于您在C中工作,因此无法通过引用传递指针。 作为替代方法,您可以将指针传递给指针:

     int lcreate(char *fname, element **list) { // ... *list = malloc(sizeof(element)); (*list)->next = null; (*list)->val = c; // ... } 

    基本上, lcreate所有代码都需要引用*list而不仅仅是list 。 或者,您可以将指向现有列表的指针作为输入,并返回指向列表的指针,因此在main您可以使用以下内容: list = lcreate("list.txt", list);

    fileNULL ,您永远不会为其分配文件句柄。

    main函数中,您还将按值传递给lcreate 。 在lcreate()函数中,您将覆盖list的本地副本,而不是更改main函数中list的值。 由于list初始化为NULL ,因此在调用list->val

    是的 – 其他人对FILE指针的说法,并且按值传递而不是引用lcreate() ,是真的。

    你也没有从lcreate()返回列表的大小 – 你应该通过返回值或指针参数返回它。

    您试图在main()函数中迭代列表4次,但列表中可能少于4个项目。 如果list为NULL,最终printf()将导致分段错误。

    如果在进行这些更改后仍然存在问题,我建议您在代码中添加跟踪,以确定何时发生分段错误。

    更新:

    还要记得在遍历列表后释放你已经分配的内存,否则你最终会出现内存泄漏(虽然实际上这对你来说不是一个问题,因为程序结束了,但释放内存是进入的好习惯)。

    我也可以看到另外一个问题。 在lcreate()的while语句中,if语句malloc的true子句是一些内存并将其分配给list但是elem没有更新。

     while ((c = getc(file)) != EOF) { if(list == NULL) { list = (element*)malloc(sizeof(element)); if(list == NULL) { return 0; } list->val = c; } else { 

    下一次通过while循环list不会是非null但是elem仍然是null所以elem-> next的赋值会尝试依赖空指针,从而导致分段错误(顺便说一句,这意味着你试图访问内存,尚未分配给您的流程): –

     else { elem->next=(element*)malloc(sizeof(element)); 

    正如其他人指出的那样,你也没有将list返回到main,所以当你点击printf()循环时它仍然是NULL。

    最后,在查看这些问题时,调试器是您的朋友。 您将确切地看到哪条线触发了seg故障以及变量的状态。

    通过检查非null pinter来检查malloc是否成功会很好。 此外,您可能希望在while之外分配head / first链接,以避免每次在while循环中对头进行空检查。 当然,这些都是优化,万一你的链表变得非常大!

      以上就是c/c++开发分享为什么这个C链表程序会出现“分段错误”?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/522044.html

      (0)
      上一篇 2020年12月9日
      下一篇 2020年12月9日

      精彩推荐