简体   繁体   中英

memcpy prepending instead mem write?

char str[50];
   char strToCopy[16];
   int numberOfBytesToFill = 7; // fills 1st n bytes of the memory area pointed to
   char charToFillInAs = '*'; //48: ascii for '0' // '$';
   void* targetStartAddress = str;
   strncpy(strToCopy, "tO sEe The wOrLd", strlen("tO sEe The wOrLd")+1);
   puts(strToCopy); // print

   strcpy(str, "Test statement !@#$%^&*()=+_~```::||{}[]");
   puts(str); // print

   memset(targetStartAddress, charToFillInAs, numberOfBytesToFill); // fill memory with a constant byte (ie. charToFillInAs)
   puts(str); // print

   memcpy(targetStartAddress, strToCopy, strlen(strToCopy)+1); // +1 for null char   
   puts(str); // print

The output is:

tO sEe The wOrLd
Test statement !@#$%^&*()=+_~```::||{}[]
*******atement !@#$%^&*()=+_~```::||{}[]
tO sEe The wOrLd*******atement !@#$%^&*()=+_~```::||{}[]

Hence, my question is:

why:

tO sEe The wOrLd*******atement !@#$%^&*()=+_~```::||{}[]

instead of

tO sEe The wOrLd\0#$%^&*()=+_~```::||{}[]
with '\0' as the null char

Thank you.

strncpy(strToCopy, "tO sEe The wOrLd", strlen("tO sEe The wOrLd")+1);

This is the wrong way to use strncpy . You should specify the size of the output buffer, not the size of the input. In this case the output buffer is 16 bytes, but you are copying 17 bytes into it, which results in undefined behavior.

Note that even if you do specify the output buffer size, strncpy won't write the null terminator if the string is truncated so you'd need to add it yourself:

strncpy(strToCopy, "tO sEe The wOrLd", sizeof(strToCopy));
strToCopy[sizeof(strToCopy)-1] = '\0';  //null terminate in case of truncation.

For this reason, some people prefer to use another function. For example, you can implement a safe copy function by using strncat :

void safeCopy(char *dest, const char *src, size_t destSize) {
    if (destSize > 0) {
        dest[0] = '\0';
        strncat(dest, src, destSize-1);
    }
}

To be used like:

safeCopy(strToCopy, "tO sEe The wOrLd", sizeof(strToCopy));

Note also that you won't actually see the null character and what comes after it as in your expected output. The output will simply stop at the null terminator because it indicates the end of the string.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM