C内存重叠?
我正在尝试将32字节字符串的前16个字节复制到C内存重叠?,c,string,memcpy,cstring,memmove,C,String,Memcpy,Cstring,Memmove,我正在尝试将32字节字符串的前16个字节复制到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));
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));
输出如下
HELLO-HELLO-HELLO-HELLO-HELLO-12
32
HELLO-HELLO-HELLHELLO-HELLO-HELLO-HELLO-HELLO-12
48
我只希望在dest
中收到HELLO-HELLO-HELL
。
dest
的前16个字节实际上包含预期结果
为什么dest
的容量超过了它的实际容量?
为什么它的长度是16+32=48
?
是否有办法只将
src
的前16个字节复制到dest
?分配给dest的16个字节需要包含一个尾随空('\0')的字节——因为您写入了16个字节,所以您有一个以非空结尾的字符串
由于您所在的计算机以特定的方式组织堆栈,因此您将继续经过dest的末尾,然后打印src
因此,要复制16个字节,分配17个字节为后面的null留出空间,并对其进行初始化
unsigned char dest[17]={0};
或者,在复制它之后,null终止它:
memcpy(dest, src, 16); // COPY
dest[16]='\0';
您没有考虑字符串以null结尾这一事实。“HELLO…”字符串常量的末尾有一个“\0”字符。看看
这将为你指明正确的方向。memcpy不提供C字符串的帮助—只提供原始内存。如果要复制16个字符的字符串,需要17个字符的缓冲区,并确保最后一个字符是
\0
。这里发生的是从一个未终止的字符串生成垃圾(在本例中是src字符串中的剩余字符)的经典打印。请看一下。使用strcpy或strncpy而不是memcpy,并了解如何使用C字符串,这些字符串与其他语言中的字符串不同,而是以null结尾的字符数组。此外,分配给src的字符串长度为33个字符。虚假初始化是降低性能的好方法。在这种情况下还不错,因为你只需要做17倍的初始化工作,因为缓冲区不是太大。18秒!你赢了,假的。我不认为这意味着你认为它的意思。