c语言strcpy、strncpy、memcpy内存拷贝比较
c语言strcpy、strncpy、memcpy内存拷贝比较/*********************************************************参考:https://blog.csdn.net/zhanghuan_wangkai/article/details/51674935**************************************...
c语言strcpy、strncpy、memcpy内存拷贝比较
strcpy、memcpy区别
strcpy和memcpy主要有以下3方面的区别。
1、复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。企业中使用memcpy很平常,因为需要拷贝大量的结构体参数。memcpy通常与memset函数配合使用。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。因此strcpy会默认复制字符串的结束符“\0”,而memcpy,当3个参数决定复制的长度包括了\0字符时,则也会复制\0,不包括\0字符的长度,则不会复制\0。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
strcpy、strncpy的区别
strcpy()是依据源串的/0作为结束判断的,不检查目标空间Buffer的Size,如果目标空间不够,就有BufferOverflow问题。
strncpy(char* dst,char * src, size_t count),从源地址src拷贝count字符到目的地址dst,虽有count做限制,当strlen(src)>strlen(dst)时,还是会存在目标空间地址越界,所以使用strncpy的正确方法应该是,首先对dst空间用memset清零, strncpy(char dst,char * src, sizeof(dst)-1)。*
strncpy和memcpy的区别
如果只是操作字符串,其实这两个函数差别不大,类型转换都不是问题。
有一点差别就是当你要拷贝大于原字符串长度的时候,也就是 n 大于源字符串长度,strncpy 会用 ‘\0’ 来填充,而 memcpy 只完全复制源地址空间的字符,包括末尾的一个\0,再多余的字符不会出现用多个\0来填充,而是保持目的地址的已有的内存值,所以超过src长度的内存区域在目的地址内存中是不确定的。
嵌入式编程需要注意,比如串口里不传输字符串,而是传输十六进制比特流[^1]。
因为16进制流里难免出现0x00,如果用 strncpy 来拷贝数据,在出现0x00的地方就认为是字符串结束了,然后剩余的长度都会用0x00(‘\0’) 填充。而memcpy就不会出现这个问题。
例
数据流: a1 a2 a3 a4 a5 a6 a7 a8 a9 00 b0 b1 b2 b3 b4 b5 b6 b7 b8 b9
用strncpy之后:a1 a2 a3 a4 a5 a6 a7 a8 a9 00 00 00 00 00 00 00 00 00 00 00
用memcpy之后:a1 a2 a3 a4 a5 a6 a7 a8 a9 00 b0 b1 b2 b3 b4 b5 b6 b7 b8 b
代码
/*********************************************************
参考:
https://blog.csdn.net/zhanghuan_wangkai/article/details/51674935
* *******************************************************/
#include <stdio.h>
#include<string.h>
#include <assert.h>
void *my_memcpy(void *memTo, const void *memFrom, int size)
{
//入口参数检查
assert((memTo != NULL) && (memFrom != NULL));
char *tempFrom = (char *)memFrom;
char *tempto = (char *)memTo;
//循环size次,复制memFrom的值到memTo中
while (size-- > 0)
{
*tempto++ = *tempFrom++;
}
return memTo;
}
int main()
{
char *strSrc = "hello wrold";
char strDest[7] = {0};
//strpcy-------------------------
strcpy(strDest, strSrc);
printf("strDest:%s\n", strDest);//strDest:hello wrold\0,会拷贝strSrc的末尾\0,当strlen(strSrc)>sizeof(strDest),strDest越界
char s1[] = "12345";
char s2[] = "678";
strcpy(s1, s2);
printf("s1:%s\n", s1);//s1内存:678\05\0,会拷贝strSrc的末尾\0
//栈内存是一个自顶向下分布的数据结构,那么越先定义的变量地址就越高,越后定义的地址就越低。 \
s比d定义在前, 那么s得到了高地址, 而d得到了相对低的地址
char s[] = "abcdefghi";
char d[] = "abc";//末尾\0
strcpy(d, s);
printf("d=%s,\ns=%s", d, s);//s中内存:efghi0ghi0,输出efghi
/*
低------->高地址,低地址先存储d数组,共4个字符,包括\0,
abc0abcdefghi0
strcpy拷贝后,d数组越界,破坏了s数组里的数据
abcdefghi0ghi0
*/
//strnpcy------------------------------
//如果strlen(src)的值小于len,dst数组就用\
额外的\0字节填充到len长度,如果strlen(src)的值大于或等于len,那么只有len个字符被复制到dst中。
char message[] = "abcd";
strncpy(message, "abcde", 5);
printf("message:%s\n", message);//strlen(src)>strlen(dst),message内存值:abcde??乱码
char message0[] = "abcd";
strncpy(message0, "abcde", 7);
printf("message0:%s\n", message0);//后面会填充2个0,凑成7个字符,message内存值:abcde00
char message1[] = "abcdefghik";
strncpy(message1, "abe", 5);
printf("message1:%s\n", message1);//message1内存值,abe后自动填充2个0,凑成5个字符:abe00fghik0----strlen(src)的值小于len
char message3[] = "abcdefghik";
strncpy(message3, "abe", 4);
printf("message3:%s\n", message3);//message3内存值,abe后自动填充1个0,凑成4个字符:abe0efghik0----strlen(src)的值小于len
char message2[] = "abcdefghik";
strncpy(message2, "abe", 3);
printf("message2:%s\n", message2);//message2内存值,刚好拷贝abe3个字符:abedefghik0----strlen(src)的值等于len
char message4[] = "abcdefghik";
strncpy(message4, "mnq", 2);
printf("message4:%s\n", message4);//message4内存值,只拷贝前2个字符:mncdefghik0----strlen(src)的值大于len
//memcpy,src和dest所指内存区域不能重叠--------
char message6[] = "abcdefghik";
memcpy(message6, "mnq", 2);
printf("message6:%s\n", message6);//message6内存值,只拷贝前2个字符:mncdefghik0,与strncpy一样----strlen(src)的值大于len
char message8[] = "abcdefghik";
memcpy(message8, "mn", 2);
printf("message8:%s\n", message8);//message8内存值,只拷贝前2个字符:mncdefghik0,与strncpy一样----strlen(src)的值等于len
char message7[] = "abcdefghik";
memcpy(message7, "abe", 5);
printf("message7:%s\n", message7);//message7内存值,只拷贝sizeof("abe")共4个字符:abe0defghik0,内存中第5个(多余)\
字符是未知的,而strncpy是默认用\0填充-----strlen(src)的值小于len
return 0;
}
运行结果

参考
1.https://blog.csdn.net/gu332523602/article/details/78428819
更多推荐


所有评论(0)