我很遗憾地问我认为这是一个愚蠢的问题,但我觉得我的概念非常错误,需要解决它。
我已经为列出的链接提供了这个代码,我已经玩了一段时间来解决它的问题:
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 *,它会正确地添加和迭代然后有点...分解和覆盖?那是怎么回事?毫无头绪。
另外如果我应该在其他地方张贴这个,请告诉我。
我也发现了这篇文章,但我认为这个问题来自于我的案例中的另一个问题,尽管不完全确定
答案 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)
getline
是reusing the pointer of line,用于存储char数据。使用strdup
将其存储在链接节点中。