我确实知道memcpy对于重叠区域通常是不安全的,我确实理解其中的原因。但我的问题是:做这样的事情通常是否安全?
#include <stdio.h>
#include <string.h>
int main(void) {
int a = 5;
memcpy(&a, &a, sizeof a);
printf("%d", a);
return 0;
}
如果没有,我可以认为哪种硬件/软件配置是安全的?
edit1:所以我会改进我的问题:这个函数的通常*实现会认为它安全吗? (当然不在C标准之内)
edit2:我知道这个问题很容易解决,但是这个奇怪的用例引起了一个问题,这个问题没有被其他答案直接解决。
*通常我指的是大多数使用和部署系统的实现(例如linux,windows ......)
答案 0 :(得分:6)
来自C标准:
#include <string.h>
void *memcpy(void * restrict s1,
const void * restrict s2,
size_t n);
memcpy函数将s2指向的对象中的n个字符复制到s1指向的对象中。如果在重叠的对象之间进行复制,则行为未定义。
由于a
与a
完全重叠,因此此代码不安全,您永远不能认为它是安全的。
在平台和编译器的某些组合上可能是安全的,但您仍然无法认为它是安全的,您必须找到一些保证它具有某些特定行为的文档
答案 1 :(得分:1)
memcpy
到同一地区是否安全?
没有。这将调用未定义的行为。复制源和目标源不得重叠。
memcpy
在C99中有以下原型:
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
restrict
同时使用s1
和s2
表示副本和目标的来源不应重叠。 (它不保证它们不重叠)。
答案 2 :(得分:0)
我强烈反对取决于未定义的行为,无论代码是否只在一个平台上运行。众所周知,C优化器利用了未定义的行为,并且只需更新C编译器即可破坏代码。
要详细了解依赖于未定义行为的危险(包括示例),请阅读Towards Optimization-Safe Systems: Analyzing the Impact of Undefined Behavior. Xi Wang, Nickolai Zeldovich, M. Frans Kaashoek, and Armando Solar-Lezama。