这是一个我无法回避的非常神秘的行为。
我正在尝试编辑一个变量的字符串,然后再次复制到源。我有以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char word[100] = "1 hash";
char* sp = malloc(100);
sp = strchr(word, ' ');
sp++;
// the "bug" still happens with strcpy instead of strncpy
strncpy(word, sp, 100);
printf("%sn", word);
}
输出为:
hhsh
应该是hash
。
奇怪的是;1散列";是我发现的唯一一个发生此错误的字符串。我尝试的所有其他字符串都给出了预期的输出。例如:"1 huhanh" -> huhanh
或"3 a h c" -> a h c
如有任何帮助,我们将不胜感激。
您有未定义的行为。malloc
指针被忽略。
因此,当您执行strcpy
时,sp
和word
是相同字符串的一部分。
这是UB。这意味着它可能会断开。它可能会起作用。它可能会产生不正确的结果。
在这种情况下,我们无法预测字节的获取和存储顺序。对于某些序列,它将[看起来]起作用。对于其他字节,我们可能会从上一个字节中提取一个而不是输入的字节,而是输出的字节。
这是更正后的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main()
{
char word[100] = "1 hash";
char *copy = malloc(100);
char *sp = strchr(word, ' ');
sp++;
strncpy(copy, sp, 100);
printf("%sn", copy);
}
更新:
谢谢你的回答。我确实没有意识到它们都是同一根绳子的一部分。在提供的示例代码u中,指针
sp
是否仍然必须存在佩德罗·维尼修斯
是的,因为它是从复制的地方。请注意,您从strchr
获得了指针。然后,您递增。正是这个更新的值成为源地址。
这个是干净的代码。
但是,你可以做:
strncpy(copy, strchr(word, ' ') + 1, 100);
但是,我不会这么做。IMO;太可爱了";。原始的sp
代码将同样快速地执行。而且,它更容易阅读。它让你做一些错误检查:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main()
{
char word[100] = "1 hash";
char *copy = malloc(100);
char *sp = strchr(word, ' ');
if (sp != NULL) {
sp++;
strncpy(copy, sp, 100);
}
else
*copy = 0;
printf("%sn", copy);
}
char* sp = malloc(100);
问题是,这个分配的内存根本没有被使用。strchr
返回指向原始字符串中的字符的指针。根据文件
目的地和来源不应重叠
此代码
char* sp = malloc(100);
sp = strchr(word, ' ');
分配一些内存,然后将其泄漏。sp最终指向堆栈上的"单词">