字符串(memcpy)

【1】内存拷贝函数应该如何实现?

函数原型:void * memcpy(void *memTo,memFrom,size_t size)

返回值类型:void *

参数1:void *memTo; 需要拷入的目的指针

参数2:void *memFrom; 需要拷贝的起始指针

参数3:size_t size; size_t代表unsigned int 表示拷贝的字节数

(1)具体实现版本V1.0。示例代码如下:

 1 void * memcpy(void *memTo, const void *memFrom, size_t size)
 2 {
 3     assert((memTo != NULL) && (memFrom != NULL));
 4     char *tempFrom = (char *)memFrom;
 5     char *tempTo = (char *)memTo;
 6     while (size-- > 0)
 7     {
 8         *tempTo++ = *tempFrom++;
 9     }
10     return memTo;
11 }

但是,如果用户如下调用就会出错。请看下面这种情况,两种版本的比较:

(2)具体改进实现V2.0。示例代码如下:

 1 #include <iostream>
 2 #include <cassert>
 3 using namespace std;
 4 
 5 void * MyMemMove(void *dst, const void *src, int count)
 6 {
 7     assert((dst != NULL) && (src != NULL));
 8     char* tempFrom = (char *)src;
 9     char* tempTo = (char *)dst;
10     if (tempTo <= tempFrom || tempTo >= (tempFrom + count)) 
11     {
12         while (count--) 
13         {
14             *tempTo++ = *tempFrom++;
15         }
16     }
17     else 
18     {
19         tempTo = tempTo + count - 1;
20         tempFrom = tempFrom + count - 1;
21         while (count--) 
22         {
23             *tempTo-- = *tempFrom--;
24         }
25     }
26     return  dst;
27 }
28 
29 void *memcpy(void *memTo, const void *memFrom, size_t size)
30 {
31     assert((memTo != NULL) && (memFrom != NULL));
32     char *tempFrom = (char *)memFrom;
33     char *tempTo = (char *)memTo;
34     while (size-- > 0)
35     {
36         *tempTo++ = *tempFrom++;
37     }
38     return memTo;
39 }
40 
41 void main()
42 {
43     char p1[256] = "hello,world!";
44     char p2[256] = "hello,world!";
45     MyMemMove(p1 + 1, p1, sizeof(p1));
46     memcpy(p2 + 1, p2, sizeof(p2));
47     cout << p1 << endl;   //hhello,world!
48     cout << p2 << endl;   //hhhhhhhhhhhhhh.....  error!!!!!
49     system("pause");
50 }

OK,如果用户如上调用的话,版本V1.0问题显而易见,也就是所谓的重叠内存拷贝。

这个时候就要考虑拷贝的起始地址与目的地址的大小关系。首先就要进行一步判断。如上例所示。

(3)因为内存拷贝可能不仅仅是几十个字节的任务,在实际的工作中,面对大量的字节拷贝,我们也要防止用户输入比较极端,不小心把起始地址与目的地址输入成了一个地址,那么,为了不浪费cpu做无用功。最后综合考虑,再判断一下两个指针的异同。

所以,比较满意实现V3.0。示例代码如下:

 1 void * MemMove(void *dst, const void *src, int count)
 2 {
 3     assert((dst != NULL) && (src != NULL));
 4     char* tempFrom = (char *)src;
 5     char* tempTo = (char *)dst;
 6     if (tempTo <= tempFrom || tempTo >= (tempFrom + count)) 
 7     {
 8         while (count--) 
 9         {
10             *tempTo++ = *tempFrom++;
11         }
12     }
13     else 
14     {
15         tempTo = tempTo + count - 1;
16         tempFrom = tempFrom + count - 1;
17         while (count--) 
18         {
19             *tempTo-- = *tempFrom--;
20         }
21     }
22     return  dst;
23 }

另外....

memcpy函数用于将指定长度的内容从一个地址复制到另一个地址。在引用中的示例中,memcpy被用来将字符串"myname"复制到结构体person的name成员中。memcpy的第一个参数是目标地址,第二个参数是源地址,第三个参数是要复制的字节数。所以在这个例子中,strlen(myname) + 1表示复制的长度为字符串长度加上一个字节来包含字符串的结尾字符'\0'。 在引用的代码中,测试了memcpy函数将字符串从一个字符数组复制到另一个字符数组。同样,在这个例子中,strlen(ch_src) + 1表示复制的长度为字符串长度加上一个字节。 所以,总的来说,memcpy函数可以用于复制字符串到不同的地址,只需提供源地址和目标地址以及要复制的长度即可。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [字符串memcpy](https://blog.youkuaiyun.com/xingyuan1hao/article/details/52262418)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [C\C++字符串操作&memcpy函数的底层实现](https://blog.youkuaiyun.com/weixin_42375828/article/details/131140762)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值