将char *添加到链接列表不起作用

时间:2015-03-29 18:48:59

标签: c list linked-list getline

我很遗憾地问我认为这是一个愚蠢的问题,但我觉得我的概念非常错误,需要解决它。

我已经为列出的链接提供了这个代码,我已经玩了一段时间来解决它的问题:

http://www.thegeekstuff.com/2012/08/c-linked-list-example/

现在我需要以相同的方式操作列表,但是我不想将结构作为int val,而是希望它是char * val,所以结构就像:

struct nodoTemas{
    char * nombreTema;
    struct nodoSuscriptor * nodoCerodeSuscriptores;
    struct nodoTemas * next;
};

我从这样的文件中读取char *:

while ((read = getline(&line, &len, fp)) != -1) {
add_to_list(line,true);

}

我无法在概念层面上完成差异。是的getline为char添加了一个\ n,所以它有点混淆了我的fprintf和什么不是,但是我从执行代码得到的结果是:

 creating list with headnode as [tema1
 ]


  Adding node to end of list with value [tema2
 ]

  -------Printing list Start------- 

  [tema2
 ] 

  [tema2
 ]

什么时候应该

-------打印列表开始-------

  [tema1
 ] 

  [tema2
 ]

因为这是它首先获得的!我只是没有看到差异,我重新阅读有关char *,char和char []的信息,我重读了getline man,我根本不明白为什么如果链接中的代码有效完全没有int的,如果我使用char *,它会正确地添加和迭代然后有点...分解和覆盖?那是怎么回事?毫无头绪。

另外如果我应该在其他地方张贴这个,请告诉我。

我也发现了这篇文章,但我认为这个问题来自于我的案例中的另一个问题,尽管不完全确定

Adding Char Value to a Linked List using Looping [C]

2 个答案:

答案 0 :(得分:1)

正如我在原comment中猜到的那样,您遇到了问题,因为您没有管理由getline()分配并由add_to_list()正确使用的空间。

你说你正在使用:

while ((read = getline(&line, &len, fp)) != -1) {
    add_to_list(line, true);
}

您尚未显示add_to_list()的代码,但症状是您只需在列表中指定line(指针)的值,而不是为该空间制作副本功能。您可以通过以下方式表面修复代码:

char *line = 0;
size_t len = 0;
ssize_t nbytes;
while ((nbytes = getline(&line, &len, fp)) != -1)
{
    add_to_list(line, true);
    line = 0;
    len = 0;
}
free(line);

这将为每行读取分配新内存。然后add_to_list()函数可以使用它。 但是,当你释放列表时,你必须确保最终释放内存。请注意,显示的free()并非您需要的唯一身份。它会在检测到EOF之前释放由getline()预先分配的所有内存。

另一种设计是:

char *line = 0;
size_t len = 0;
ssize_t nbytes;
while ((nbytes = getline(&line, &len, fp)) != -1)
    add_to_list(line, true);
free(line);

现在您必须修改add_to_list()以复制line的数据。您仍然必须释放该行,如图所示,释放列表的代码仍然必须释放复制的数据。

  

我已经有了free(line),但你提到这不是我需要的唯一免费。介意扩大一点?是否需要释放列表中的每个节点?该列表应该在发布者 - 订阅者模型中保存主题,因此除非过程结束,我相信内存应该保留列表?

在你完成任何事情之前,没有必要放任何东西;过早的自由与永不释放一样糟糕。分配内存时,您始终必须知道何时释放内存。对于每个分配,请确保您可以确定如何释放内存以及何时释放内存。

有时候合法的决定是永远不会释放内存(或者直到进程退出),但对于长时间运行的进程,这是需要仔细决定的。即使这样,只有指针(或指针链)允许你进入内存才是合法的。如果没有办法访问内存,那么它就会被泄露并浪费掉,这在大型程序中并不是一个好主意(特别是在长期运行的程序中)。

如果您为列表中的每个项目分配了内存,则在释放该项目时,您需要为列表中的每个项目释放内存。当您拆除整个列表时可能会发生这种情况,或者当您决定不再需要某个项目时,它可能会零碎地发生。重要的是你知道内存已经分配,​​并且在不再需要它时它将被释放。如果你不确定这一点,你将泄漏内存,你的程序可能会增长,直到内存不足为止。

如果可能,请使用valgrind之类的工具来帮助您跟踪内存滥用情况 - 它会发现内存泄漏和一些内存滥用(读取和写入超出范围)。

答案 1 :(得分:0)

getlinereusing the pointer of line,用于存储char数据。使用strdup将其存储在链接节点中。