2011-08-30 32 views
2

每当我有一个函数,它接受一个C字符串,并希望它的值存储链表里面,我应该做这样的...我的函数应该拷贝`char *` - 参数吗?

void add(char* str) 
{ 
    node *n = malloc(sizeof(node)); 
    n->value = str; 
} 

或者说...

void add(char* str) 
{ 
    node *n = malloc(sizeof(node)); 
    char* copy = malloc(strlen(str)+1); 
    strcpy(copy, str); 
    n->value = copy; 
} 

在此先感谢。

+2

无关,但我假设你的意思是'malloc(sizeof(* n))''malloc(strlen(str) +1)'。 –

+0

@rob不同意第一个。纠正了第二个。谢谢。 – imacake

+1

您正在分配一个大小为“节点*”而不是“节点”的指针。你也可以使用'strdup'来复制字符串,而不是'malloc' +'strcpy' – Hasturkun

回答

7

它真的取决于来自哪里的论据,以及你对这些论点的意图是什么。

如果您知道作为参数传递的字符串在链表的整个生命周期中始终可用,并且它们未被修改或释放,或者没有会影响链接的任何副作用的函数-list,那么你可以简单地复制指针而不费心去复制整个字符串。

如果上述任何一个不正确(我的意思是,如果您不知道上述答案之一),那么复制整个字符串会更安全。

一些具体的例子:

  • 你正在开发的小型应用程序读取CSV文件,存储在分类链接列表中的值,然后把一个值返回到一个XML文件中:你有控制字符串的整个生命周期,您不必复制它们。

  • 你正在写一个链接列表库,可能在网上发布,可能被数百人在所有类型的领域中活跃使用:你不知道将传递给你的库的内容是什么,知道库用户在操作链表之前是否会释放字符串,然后复制整个字符串。

也注意到,这种设计决定的是更好地记录某个地方:它是作为一个开发者,以明确你的函数将指针存储而不复制字符串,或者你会复制字符串和你的责任将需要另一个函数调用来释放内存。 (这被称为design by contract:你使用你的函数和函数本身建立了代码之间的契约,你最好尊重它,否则你将会遇到问题,以数据损坏或软件崩溃的形式出现)。一种可能的方式可以让您的意图清晰明了,就是使用适当放置的const关键字。

+0

+1按合同设计。这确实是关键 - 你必须建立,遵循和记录你要遵循的约定。如果我能指出另一个+1,指出理想的约定会根据您的应用而变化。 –

1

str的所有权是什么?这是一个malloc编辑缓冲区与动态数据?在程序中调用add是否将指向链接列表的所有权?

没有正确答案,因为它取决于str的使用方式。

0

我宁愿更喜欢第二个选项,因为: - - 即使它工作,代码也不可维护 - 如果原始字符串str被删除,第一个选项会留下悬空指针的较大间隔。没有办法确定程序中实际制作了多少个指针str。 - 任何内存工具也会抱怨,导致输出变臃肿,因此难以调试任何实际的内存问题

+0

很抱歉,您现在支持#1或#2 ...:s? – imacake