real use case of memcpy - and why not taking a simple asignment instead?

StackOverflow https://stackoverflow.com/questions/23095274

  •  04-07-2023
  •  | 
  •  

문제

memcpy copies n bytes from the source to the destination. (linux man page)

and a simple assignment is doing the same, right?

So where are the differences, and what would be a real use case of memcpy?

도움이 되었습니까?

해결책

Yes and no. Simple assignment will copy values, as you say, so assigning a standard variable, be it a standard data type or a struct, will work fine. The issue typically comes when using arrays. Take the following example:

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!

For the array cases above, memcpy allows us to copy the data, so to perform str1 = str2, we'd actually have to write memcpy(str1, str2, 50);

다른 팁

Because memcpy allows you to copy arrays with just an instruction and because it is typically faster than a hand-made loop (usually it's implemented in highly optimized assembly which copies most of the stuff in chunks as large as machine words).

While you can emulate the function of memcpy with simple assignments, memcpy will compile usually into a CPU instruction which copies a whole memory area as fast as possible.

You can easily test the difference using an example program:

#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;
}

If you profile this program you get more or less this result:

Profiler Result

In simple cases the compiler optimiser detects the simple attempt to "move memory" and automatically replaces the for loop with a simple "memory move" instruction.

Compile this example, and check the disassembly generated by the C++ compiler to see the difference.

Add a printf("%s%s",a,b); to make sure the compiler doesn't remove everything for optimisation.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top