繁体   English   中英

memcpy前置而不是mem写?

[英]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

输出为:

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

因此,我的问题是:

为什么:

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

代替

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

谢谢。

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

这是使用strncpy的错误方法。 您应该指定输出缓冲区的大小,而不是输入的大小。 在这种情况下,输出缓冲区为16字节,但是您正在向其中复制17字节,这将导致未定义的行为。

请注意,即使您确实指定了输出缓冲区的大小,如果字符串被截断, strncpy也不会写空终止符,因此您需要自己添加它:

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

因此,有些人喜欢使用其他功能。 例如,您可以使用strncat实现安全复制功能:

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

使用方式如下:

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

还要注意,您实际上不会看到空字符以及它后面的预期输出。 输出将仅在空终止符处停止,因为它指示字符串的结尾。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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