strcpy vs. memcpy
Asked Answered
B

9

98

What is the difference between memcpy() and strcpy()? I tried to find it with the help of a program but both are giving the same output.

int main()
{
    char s[5] = { 's', 'a', '\0', 'c', 'h' };
    char p[5];
    char t[5];
    strcpy(p, s);
    memcpy(t, s, 5);
    printf("sachin p is [%s], t is [%s]", p, t);
    return 0;
}

Output

sachin p is [sa], t is [sa]
Bagwig answered 24/5, 2010 at 16:9 Comment(1)
See #2885374Paste
M
142

what could be done to see this effect

Compile and run this code:

void dump5(char *str);

int main()
{
    char s[5]={'s','a','\0','c','h'};

    char membuff[5]; 
    char strbuff[5];
    memset(membuff, 0, 5); // init both buffers to nulls
    memset(strbuff, 0, 5);

    strcpy(strbuff,s);
    memcpy(membuff,s,5);

    dump5(membuff); // show what happened
    dump5(strbuff);

    return 0;
}

void dump5(char *str)
{
    char *p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%2.2x ", *p);
        ++p;
    }

    printf("\t");

    p = str;
    for (int n = 0; n < 5; ++n)
    {
        printf("%c", *p ? *p : ' ');
        ++p;
    }

    printf("\n", str);
}

It will produce this output:

73 61 00 63 68  sa ch
73 61 00 00 00  sa

You can see that the "ch" was copied by memcpy(), but not strcpy().

Medici answered 24/5, 2010 at 22:14 Comment(2)
Hello, I know that post is old, but I have two questions regarding it. First - printf("%2.2x ", *p); - why did You limit printf to 2.2 ? Besides I can see NO dot at all... Second - printf("%c", *p ? *p : ' '); - what does this test really check? If *p ? Thanks in advance for Your answer!Degrease
In a printf statement, "x" means "base 16". "2.2" means: two and only two digits. The *p test means: "if you hit a null, print a space."Medici
A
115

strcpy stops when it encounters a NUL ('\0') character, memcpy does not. You do not see the effect here, as %s in printf also stops at NUL.

Averir answered 24/5, 2010 at 16:11 Comment(3)
@Sachin: Initialize p and t to something (all blanks, for example), then after copying, compare p[3] to t[3]. The strcpy didn't go beyond p[2], where it found the null character, but the memcpy as directed copied five characters.Eviscerate
Minor nit-pick: strcpy stops when it encounters the NUL character (one "L"). NULL (two "L"s) is a compile-time constant for a pointer guaranteed not to point to any valid object.Gillard
if dest and src overlap, strcpy will throw out a seg-fault?Foxtail
C
13

strcpy terminates when the source string's null terminator is found. memcpy requires a size parameter be passed. In the case you presented the printf statement is halting after the null terminator is found for both character arrays, however you will find t[3] and t[4] have copied data in them as well.

Cantabrigian answered 24/5, 2010 at 16:12 Comment(0)
S
10

strcpy copies character from source to destination one by one until it find NULL or '\0' character in the source.

while((*dst++) = (*src++));

where as memcpy copies data (not character) from source to destination of given size n, irrespective of data in source.

memcpy should be used if you know well that source contain other than character. for encrypted data or binary data, memcpy is ideal way to go.

strcpy is deprecated, so use strncpy.

Salespeople answered 5/12, 2012 at 12:36 Comment(3)
I don't know where did you see strcpy() being deprecated.Nikkinikkie
@RohanBari It's a royal outrage if this is someone with only MSVC experience speaking about "deprecated functions" all over again for the billionth timeCoachman
strcpy() is not deprecated, it's only discouraged (because strncpy() is less vulnerable to buffer overruns). Not the same thing at all.Medici
I
5

The main difference is that memcpy() always copies the exact number of bytes you specify; strcpy(), on the other hand, will copy until it reads a NUL (aka 0) byte, and then stop after that.

Inborn answered 24/5, 2010 at 16:11 Comment(0)
Z
3

Because of the null character in your s string, the printf won't show anything beyond that. The difference between p and t will be in characters 4 and 5. p won't have any (they'll be garbage) and t will have the 'c' and 'h'.

Zygospore answered 24/5, 2010 at 16:12 Comment(0)
T
3
  • Behavior difference: strcpy stops when it encounters a NULL or '\0'
  • Performance difference: memcpy is usually more efficient than strcpy, which always scan the data it copies
Trustbuster answered 19/1, 2017 at 18:33 Comment(1)
Performance-wise, it should really depend on the compiler and the platform. I've tested on two different environments and got these results: On Linux ARMv7L, memcpy was 1.5x faster than strcpy. However, on Linux x86_64, using GCC 13.1.1 and Clang 16.0.5, strncpy and strcpy both was faster than memcpy by 10% (maybe because of a modern compiler implementation?). Your mileage may vary, so you should test it yourself.Marzi
A
2

The problem with your test-program is, that the printf() stops inserting the argument into %s, when it encounters a null-termination \0. So in your output you probably have not noticed, that memcpy() copied the characters c and h as well.

I have seen in GNU glibc-2.24, that (for x86) strcpy() just calls memcpy(dest, src, strlen(src) + 1).

Alexandros answered 16/2, 2018 at 13:18 Comment(0)
D
1

printf("%s",...) stops printing the data when null is encountered, so both the outputs are same.

The following code differentiates between strcpy and memcpy:

#include<stdio.h>
#include<string.h>

int main()
{
    char s[5]={'s','a','\0','c','h'};
    char p[5];
    char t[5];
    int i;
    strcpy(p,s);
    memcpy(t,s,5);
    for(i=0;i<5;i++)
        printf("%c",p[i]);
        printf("\n");
    for(i=0;i<5;i++)
        printf("%c",t[i]);

    return 0;
}
Defibrillator answered 10/5, 2020 at 5:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.