Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Valgrind警告:我应该认真对待吗_C_Valgrind_Overlap_Strcpy - Fatal编程技术网

C Valgrind警告:我应该认真对待吗

C Valgrind警告:我应该认真对待吗,c,valgrind,overlap,strcpy,C,Valgrind,Overlap,Strcpy,背景: 我有一个模拟fgets(character,2,fp)的小例程,除了它从字符串而不是流中获取字符。newBuff是作为参数传递的动态分配字符串,字符声明为char character[2] 例行程序: character[0] = newBuff[0]; character[1] = '\0'; strcpy(newBuff, newBuff+1); strcpy在读取每个字符时复制信息丢失 问题:Valgrind确实警告过我 此活动“源和目标” strcpy中的重叠(0x419b

背景: 我有一个模拟fgets(character,2,fp)的小例程,除了它从字符串而不是流中获取字符。newBuff是作为参数传递的动态分配字符串,字符声明为
char character[2]

例行程序:

character[0] = newBuff[0];

character[1] = '\0';

strcpy(newBuff, newBuff+1);
strcpy在读取每个字符时复制信息丢失

问题:Valgrind确实警告过我 此活动“源和目标” strcpy中的重叠(0x419b818, 0x419b819)”


我应该担心这个警告吗?

如果源和目标重叠,
strcpy()的行为正式未定义

memcpy手册页中有一条建议:

函数的作用是:将n个字节从内存区域s2复制到内存区域s1。如果s1和s2重叠,则行为未定义。s1和s2可能重叠的应用程序应改用memmove(3)


是--
strcpy
的行为仅在源和目标不重叠的情况下定义。你可以考虑<代码>斯特伦< /> >和<代码> MeMaTest< /Cord>。

<是的,你应该担心。C标准规定,strcpy的行为是源对象和目标对象重叠时的行为。未定义的行为意味着它有时可能会工作,或者可能会失败,或者它可能看起来成功了,但在程序的其他地方显示失败。

标准可能没有指定这些缓冲区重叠时会发生什么。是的,
valgrind
对此的抱怨是正确的

实际上,您很可能会发现您的
strcpy
是按从左到右的顺序复制的(例如
while(*dst++=*src++);
),这不是问题。但它仍然不正确,并且在与其他C库一起运行时可能会出现问题

一种正确的书写方法是:

memmove(newBuff, newBuff+1, strlen(newBuff));

因为
memmove
被定义为处理重叠。(虽然在这里您将遍历字符串两次,一次检查长度,一次复制。我还选择了一个快捷方式,因为
strlen(newBuff)
应该等于
strlen(newBuff+1)+1,这是我最初编写的内容。)

是的,您还应该担心您的函数在病理学上的性能不好(
O(n^2)
用于应为
O(n)
的任务。每次读取一个字符时,将字符串的全部内容向后移动一个字符是一种巨大的时间浪费。相反,您应该只保留一个指向当前位置的指针并递增该指针


如果您发现自己需要
memmove
或同等功能(在重叠的缓冲区之间复制),则几乎总是表明存在设计缺陷。通常情况下,这不仅仅是实现中的缺陷,而是接口中的缺陷。

答案是肯定的:对于某些编译器/库实现,我猜是最新的,最终会得到一个虚假的结果。请参阅以获取示例。

无论如何实现,行为都是未定义的。标准中明确规定了这一点。
strcpy
在缓冲区重叠时给出了未定义的行为
memcpy
的作用与此相同,但在其他方面与此无关。好的,我的strcpy本地手册页不包含此警告,但memcpy页包含此警告。C标准中唯一接受指向重叠内存区域的指针进行读写的函数是
memmove
wmemmove
。对于其他所有内容(包括
snprintf
!),行为未定义。即使顺序是从左到右的,也可能由于展开/重新排序和大于字节单位的复制而出现问题。我会考虑使用<代码> StcPy非常不安全,并且可能在同一库的不同版本之间出现盈亏平衡,甚至不同编译器的不同版本。我同意,尤其是关于大于字节单位的观点。我只想说清楚,我同意代码不正确,应该修改。