我有以下C代码片段,必须识别错误并建议更安全地编写它的方法:
char somestring[] = "Send money!\n";
char *copy;
copy = (char *) malloc(strlen(somestring));
strcpy(copy, somestring);
printf(copy);
所以错误是strlen忽略了字符串的尾随'\0'
,因此不会为副本分配足够的内存但是我不确定他们在编写更多内容安全
我可以使用malloc(strlen(somestring)+1))
我假设但我认为必须有比这更好的方法吗?
编辑:好的,我已经接受了答案,我怀疑我们不会期待strdup解决方案,因为它不是ANSI C的一部分。这似乎是一个非常主观的问题所以我不确定我接受的是否真的是最好的。无论如何,谢谢你的所有答案。
答案 0 :(得分:7)
我不能对上面的回答发表评论,但除了检查之外
返回代码并使用strncpy
,你永远不应该这样做:
printf(string)
但请使用:
printf("%s", string);
答案 1 :(得分:6)
char somestring[] = "Send money!\n";
char *copy = strdup(something);
if (copy == NULL) {
// error
}
或者只是将此逻辑放在单独的函数 xstrdup :
中char * xstrdup(const char *src)
{
char *copy = strdup(src);
if (copy == NULL) {
abort();
}
return copy;
}
答案 2 :(得分:4)
char somestring[] = "Send money!\n";
char *copy;
size_t copysize;
copysize = strlen(somestring)+1;
copy = (char *) malloc(copysize);
if (copy == NULL)
bail("Oh noes!\n");
strncpy(copy, somestring, copysize);
printf("%s", copy);
注意上述差异:
malloc()
的结果!strncpy()
因为strcpy()
很顽皮。在这个人为的例子中,它不会受到伤害,但不会养成使用它的习惯。修改强>
对于那些认为我应该使用strdup()
的人...只有在你对问题采取最狭隘的观点时才有效。这不仅是愚蠢的,而是忽略了一个更好的答案:
char somestring[] = "Send money!\n";
char *copy = somestring;
printf(copy);
如果你会变得迟钝,至少要擅长它。
答案 3 :(得分:3)
答案 4 :(得分:3)
Ick ...像其他人一样使用strdup()
并自己写,如果必须的话。由于您现在有时间考虑这个问题...请查看25 Most Dangerous Programming Errors at Mitre,然后考虑为什么短语printf(copy)
从不出现在代码中。那就是malloc(strlen(str))
就完全不好而言,更不用说在复制类似于"%s%n"
的时候追踪它为什么会引起很多悲伤的头痛......
答案 5 :(得分:1)
我会评论以前的解决方案,但我没有足够的代表。 在这里使用 strncpy 与使用 strcpy 一样错误(因为绝对没有溢出的风险)。 < 中有一个名为 memcpy 的函数string.h> ,它正是为了这个。它不仅显着更快,而且还可以用于在标准C中复制已知长度的字符串的正确函数。
从接受的答案:
char somestring[] = "Send money!\n";
char *copy;
size_t copysize;
copysize = strlen(somestring)+1;
copy = (char *) malloc(copysize);
if (copy == NULL)
bail("Oh noes!\n");
memcpy(copy, somestring, copysize); /* You don't use str* functions for this! */
printf("%s", copy);
答案 6 :(得分:1)
使代码更安全(更正确)的方法。
somestring
。您可以直接输出。malloc
。malloc
'ed memory。printf
。使用printf("%s", copy)
或puts(copy)
。答案 7 :(得分:1)
为Adrian McCarthy提供更多更安全代码的方法,
使用静态代码分析器,他们非常善于发现这种错误
答案 8 :(得分:0)
如果一个人真的对这样的事情感兴趣的话,更安全地写它的最好方法就是在Ada中写它。
somestring : constant string := "Send money!";
declare
copy : constant string := somestring;
begin
put_line (somestring);
end;
结果相同,那么有什么区别?
请注意,在Ada中,“string”不是一些特殊的动态构造。它是内置的字符数组。但是,Ada数组的大小可以通过您指定的数组进行声明。
答案 9 :(得分:-2)
更安全的方法是使用strncpy
代替strcpy
。该函数采用第三个参数:要复制的字符串的长度。此解决方案不会超出ANSI C,因此这将适用于所有环境(而其他方法可能只适用于POSIX兼容系统)。
char somestring[] = "Send money!\n";
char *copy;
copy = (char *) malloc(strlen(somestring));
strncpy(copy, somestring, strlen(somestring));
printf(copy);