memcpy的真实用例 - 为什么不采用简单的赋值呢?

时间:2014-04-15 21:56:37

标签: c memcpy

memcpy将n个字节从源复制到目标。 ( linux手册页

并且一个简单的assignment正在做同样的事情,对吗?

那么差异在哪里,以及memcpy的实际用例是什么?

3 个答案:

答案 0 :(得分:1)

因为memcpy允许你只用指令复制数组,因为它通常比手工制作的循环更快(通常它是在高度优化的程序集中实现的,它将大部分内容复制到像机器一样大的块中字)。

答案 1 :(得分:1)

是和否。正如您所说,简单赋值将复制值,因此分配标准变量(无论是标准数据类型还是结构)都可以正常工作。使用数组时通常会出现此问题。请看以下示例:

int p,q;
struct myStruct s1, s2;
char str1[50];
char str2[50];
// ...
// Assign stuff to all the variables
// ...
p = q;   // Fine
s1 = s2; // Fine
str1 = str2; // ERROR!

对于上面的数组案例,memcpy允许我们复制数据,因此要执行str1 = str2,我们实际上必须写memcpy(str1, str2, 50);

答案 2 :(得分:0)

虽然您可以通过简单的赋值来模拟memcpy的功能,但memcpy通常会编译成CPU指令,该指令尽可能快地复制整个存储区。

您可以使用示例程序轻松测试差异:

#include <stdlib.h>
#include <stdio.h>
#include <memory.h>

const int blockSize = 4096;

void copyA(char *a, char *b)
{
    memcpy(b, a, blockSize);
}

void copyB(char *a, char *b)
{
    for (int i = 0; i < blockSize; ++i) {
        b[i] = a[i];
    }
}

int main()
{
    char *a, *b;
    a = (char*)malloc(blockSize);
    b = (char*)malloc(blockSize);
    memset(a, 0, blockSize);
    memset(b, 1, blockSize);

    for (int i = 0; i < 80000000; ++i) {
        copyA(a, b);
        copyB(a, b);
    }

    return 0;
}

如果您对此程序进行了分析,则会得到或多或少的结果:

Profiler Result

在简单的情况下,编译器优化器会检测“移动内存”的简单尝试,并使用简单的“内存移动”指令自动替换for循环。

编译此示例,并检查C ++编译器生成的反汇编以查看差异。

添加printf("%s%s",a,b);以确保编译器不会删除所有优化内容。