我的函数应该复制“char*”参数吗?
每当我有一个需要 C 字符串的函数,并且想要将其值存储在链接列表中时,我应该这样做吗...
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;
}
提前致谢。
Whenever i have a function that takes a c-string, and want to store its value inside a linked list, should i do it like this...
void add(char* str)
{
node *n = malloc(sizeof(node));
n->value = str;
}
or rather...
void add(char* str)
{
node *n = malloc(sizeof(node));
char* copy = malloc(strlen(str)+1);
strcpy(copy, str);
n->value = copy;
}
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这实际上取决于论点来自哪里,以及你对这些论点的意图是什么。
如果您知道作为参数传递的字符串在链表的整个生命周期中始终可用,并且它们不会被修改或释放,或者没有任何函数会影响您的链表,那么您可以简单地复制指针,而不必费心复制整个字符串。
如果上述任何一项不正确(我的意思是如果您不知道上述其中一项的答案),那么复制整个字符串会更安全。
一些具体示例:
您正在开发一个小型应用程序,该应用程序读取 csv 文件,将值存储在链接列表中进行排序,然后将值写回 xml 文件:您可以控制字符串的整个生命周期,您不必复制它们。
您可能正在编写一个链接列表库,分布在网络上,可能被各个领域的数百名活跃人员使用:您不知道什么会传递到您的库,您不知道是否库用户将在操作链表之前释放字符串,然后复制整个字符串。
另请注意,这种设计决策在某处有更好的记录:作为开发人员,您有责任明确您的函数将存储指针而不复制字符串,或者您将复制字符串并需要另一个函数调用来释放记忆。 (这称为按契约设计:您在使用函数的代码和函数之间建立契约本身,您最好尊重它,否则您将会遇到问题,以数据损坏或软件崩溃的形式)。明确意图的一种可能方法是使用适当放置的
const
关键字。it really depends on where are the arguments coming from, and what are your intentions with those arguments.
if you know that the strings passed as argument are always available through the entire lifetime of your linked list, and that they are not modified nor freed, or that there is no function which would have any side-effect affecting your linked-list, then you can simply copy the pointer and not bother to copy the entire string.
if any of the above is not true (by which i mean also if you don't know the answer to one of the above), then it will be safer to copy the entire string.
some specific examples:
you are developing a small application which reads a csv file, stores the values in a linked list for sorting, then writes the values back to an xml file: you have the control over the entire lifetime of your strings, you don't have to copy them.
you are writing a linked-list library possibly, distributed on the net, possibly used by hundreds of people active in all kind of field: you don't know what will be passed to your library, you don't know if the library user will free the string before manipulating the linked-list, then you copy the entire string.
also note that this kind of design decision is better documented somewhere: it is your responsibility as a developer to make clear that your function will store the pointer without copying the string, or that you will copy the string and will need another function call to release the memory. (this is called design by contract: you establish a contract between the code using your function and the function itself, you'd better respect it or you are going to have problems, in the form of data corruption or software crash). one possible way to make your intention clear is the use of an appropriately placed
const
keyword.str
的所有权是什么?它是一个带有动态数据的malloc
ed缓冲区吗?在程序中调用add
是否会授予指向链表的指针的所有权?没有正确的答案,因为这取决于
str
的使用方式。What is the ownership of
str
? Is it amalloc
ed buffer with dynamic data? Does callingadd
in your program give ownership of the pointer to the linked list?There is no correct answer, as it depends on how
str
is being used.我更喜欢第二种选择,因为:-
- 即使有效,代码也不可维护
- 如果原始字符串 str 被删除,第一个选项会为悬空指针留下很大的间隙。无法确定程序中实际创建了多少个指针 str 的副本。
- 任何内存工具也会抱怨,导致输出臃肿,从而难以调试任何实际的内存问题
I would rather prefer the second option because:-
- Even if it works, the code is not maintainable
- First option leaves a large gap for dangling pointer, if the original string str is deleted. There is no way to determine how many copies of pointer str were actually made in the program.
- Any memory tools will also complain, causing a bloated output and thus difficult to debug any actual memory problem