strcpy, strncpy, memcpy, memmove 比较
strcpy是拷贝字符串,在拷贝结束的时候会为字符串添加一个'\0';
strncpy是拷贝字符,不会再字符串末尾添加'\0',只按给出的字符个数来拷贝,拷贝完n个字符就结束。但是,如果n比src的长度大,那么空余的部分会被'\0'填充,以保证拷贝n个字符。
所以,strnpy用法最好是自己手动添加'\0':
strncpy(dest, src, sizeof(dest) - 1); dest[sizeof(dest) - 1] = '\0'; len = strlen(dest);
strcpy和strncpy都只能接受char*,也就是字符类型的数据,如果是结构体,没办法操作。而且,这两个函数如果遇到dest和src的内存重叠会导致程序崩溃。
memcpy是内存拷贝,可以接受数组,整型,结构体,类等任何类型,它实现的是内存的拷贝。
另外需要考虑的情况:
1.dest和src的内存区域重叠。即 src+n < dest+n
例如
memcpy(dest, src, n);
如果指针dest在src之前且距离小于n,由于memcpy是升序复制,会把dest会把src末尾的部分覆盖掉,没办法达到真正的复制效果。
这种情况需要使用memmove。memmove是降序复制,从后向前复制,可以src中的数据完全复制给dest。
2.越界问题
要拷贝的字符长度大于分配的空间。
memcpy进行内存拷贝时有可能发生内存读写错误,比如length大于要拷贝的空间或大于目的空间,可能发生:
int *p = new[m]; // m < n
memcpy(dst, p, n); // 发生错误,n 超过m 了,由于p是堆内分配的,所以超过的部分不属于进程空间,发生内存读写错误。而
int p[m]; // m < n
memcpy(dst, p, n); // 不发生错误,因为定义的变量在栈里,p超过10位仍属于进程空间。
memmove 可以避免内存区域重叠问题。如果出现重叠,则采用反向复制(降序,(dest+n)--, (src+n)-- ),从后向前复制字符串。如果不重叠,则正向复制(升序,dest++, src++),从前向后复制。
浙公网安备 33010602011771号