strcpy
char* strcpy(char* des,const char* src);
strcpy把从src地址开始且含有’\0’结束符的字符串复制到以dest开始的地址空间。使用时要注意:
- des的长度 >= src的长度,否则会造成数组越界的隐患。
- src的字符串中间不要有NULL,或者说是’\0’,否则会导致字符串复制不完整的问题。
- 注意不要内存重叠。
strncpy
char* strncpy(char* dest,const char* src, size_t n);
strncpy把从src地址开始的n个字符复制到以dest开始的地址空间。使用时要注意:
- 当n < src的长度,将只复制n个从src地址开始的字符到des开始的地址空间。此时的strncpy不自动添加’\0’,旧dest的地址空间没有被完全替换,如果希望用新的n个字符作为des的地址空间的字符串输出的话,在复制结束后,需要为des的地址空间的第n位赋值’\0’。
- 当n > src的长度,复制完src的所有空间后,以NULL填充dest的地址空间直到复制完n个字符。
- src的字符串中间不要有NULL,或者说是’\0’,否则会导致字符串复制不完整的问题。
- 注意不要内存重叠。
memcpy
void *memcpy(void *dest, const void *source, size_t count);
memcpy把从source地址开始的n个字节复制到以dest开始的地址空间。使用时要注意:
1.注意不要内存重叠。
strncpy 和 memcpy 的区别
- 参数的类型差别,strncpy明确要求 char*,memcpy无要求。
- 当需要复制的内容长度 > 目标空间的长度时,strncpy会用NULL来填充复制内容不足的目标空间,而memcpy则会继续复制源地址空间的内容。
- 当需要复制的内容长度 <= 目标空间的长度时,调用它们实现的效果时一样的。
内存重叠的理解
dst目标地址,src源地址,count复制字节数。
- dst <= src 且 (dst + count) > src,即存在内存重叠,且目标地址在源地址的前面。此时调用strcpy,strncpy,memcpy都是能得到想要的复制结果。
- src < dst 且 (src + count) > dst,即存在内存重叠,且目标地址在源地址的后面。此时调用strcpy,strncpy,memcpy得到的复制结果会与预想的结果不符,这种情况下可以调用库函数memmove来完成,memmove函数中有定义了当存在内存重叠时的相应操作。
- strcpy,strncpy,memcpy定义的复制顺序都是从低地址到高地址,当出现类似第二种内存重叠时就会出现地址空间内容的混乱。而memmove则定义了相关的判断,以决定复制的顺序是从低地址到高地址,还是从高地址到低地址。