memcpy到完全相同的区域是否安全?

时间:2014-06-21 08:53:02

标签: c memcpy

我确实知道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 ......)

3 个答案:

答案 0 :(得分:6)

来自C标准:

#include <string.h>
void *memcpy(void * restrict s1,
          const void * restrict s2,
          size_t n);
  

memcpy函数将s2指向的对象中的n个字符复制到s1指向的对象中。如果在重叠的对象之间进行复制,则行为未定义。

由于aa完全重叠,因此此代码不安全,您永远不能认为它是安全的。


在平台和编译器的某些组合上可能是安全的,但您仍然无法认为它是安全的,您必须找到一些保证它具有某些特定行为的文档

答案 1 :(得分:1)

  

memcpy到同一地区是否安全?

没有。这将调用未定义的行为。复制源和目标源不得重叠。

memcpy在C99中有以下原型:

void *memcpy(void *restrict s1, const void *restrict s2, size_t n);

restrict同时使用s1s2表示副本和目标的来源不应重叠。 (它不保证它们不重叠)。

答案 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