Search code examples
cstringmemcpycstringmemmove

C memory overlap?


I am trying to copy the first 16 bytes of a 32 byte string to dest.

unsigned char src[32] = "HELLO-HELLO-HELLO-HELLO-HELLO-12";
unsigned char dest[16];

memcpy(dest, src, 16); // COPY

printf("%s\n", src);
printf("%lu\n", strlen(src));

printf("%s\n", dest);
printf("%lu\n", strlen(dest));

The output is the following

HELLO-HELLO-HELLO-HELLO-HELLO-12
32
HELLO-HELLO-HELLHELLO-HELLO-HELLO-HELLO-HELLO-12
48

I was expecting to receive HELLO-HELLO-HELL in dest only. The first 16 bytes of dest actually contain the expected result.

Why does dest more than it can actually hold? Why does it have a length of 16+32=48? Is there a way to copy only the first 16 bytes of src to dest?


Solution

  • The 16 bytes allocated for dest need to include a byte for the trailing NULL ('\0') -- since you wrote 16 bytes, you have a non-null terminated string.

    Since the computer you are on has the stack organized in a particular way, you are proceeding past the end of dest and then printing src.

    So, to copy 16 bytes, allocate 17 to leave room for the trailing null, and initialize it.

    unsigned char dest[17]={0};
    

    Alternative, after copying it, null terminate it:

    memcpy(dest, src, 16); // COPY
    dest[16]='\0';