C内存重叠?

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));

我正在尝试将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));
输出如下

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秒!你赢了,假的。我不认为这意味着你认为它的意思。