实现一个Memcpy函数:将源指针所指的区域从起始地址开始的n个字节复制到目的指针所指区域
2016-10-07 10:08
453 查看
首先肯定要先看看这两部分是不是有内存重叠?为什么?
1.因为如果有内存重叠(目的地址起始位置处于源指针所指区域之中),你再从起始位置复制的话,这样目的地址改变的时候将源地址内存里面存的东西给改变了,所以必须从高地址开始复制。这样源地址总是走得比目的地址靠近低地址,也就是目的地址永远赶不上还没有复制内容给他的源地址。所以可以正常复制
2.如果没有内存重叠,那么从起始地址开始复制,目的地址也不会对源地址还没有复制给目的地址的内容产生影响,所以可以从低地址开始复制
coding
1.因为如果有内存重叠(目的地址起始位置处于源指针所指区域之中),你再从起始位置复制的话,这样目的地址改变的时候将源地址内存里面存的东西给改变了,所以必须从高地址开始复制。这样源地址总是走得比目的地址靠近低地址,也就是目的地址永远赶不上还没有复制内容给他的源地址。所以可以正常复制
2.如果没有内存重叠,那么从起始地址开始复制,目的地址也不会对源地址还没有复制给目的地址的内容产生影响,所以可以从低地址开始复制
coding
void *memcpy(void *dst,const void *src,size_t len){ if(dst==NULL||src==NULL){ return NULL; } void *ret=dst; if(dst<=src||(char *)dst>=(char *)src+len){ //这个情况表示的是没有内存重叠,那么应该从低地址开始复制 while(len--){ *(char *)dst=*(char *)src; dst=(char *)dst+1; src=(char *)src+1; } }else{ //有内存重叠,从高地址开始复制 dst=(char *)dst+len-1; src=(char *)src+len-1; while(len--){ *(char *)dst=*(char *)src; dst=(char *)dst-1; src=(char *)src-1; } } return ret; }
相关文章推荐
- 实现存储器块拷贝功能 ,将 16 个 4字节 的字数据从源地址 复制到目的地址
- 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
- 习题 8.19(1) 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
- 指针版的PStash(用一个void指针数组, 来保存存入元素的地址) 附模板化实现 p321
- 一个链表的每个节点,有一个指向next指针指向下一个节点,还有一个rand指针指向这个链表中的一个随机节点或NULL,现在要求复制一个单链表来实现这个链表,返回复制后的新链表。
- 【c语言】编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间
- java实现输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head
- 请编写实现malloc()内存分配函数功能一样的代码。给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
- 实验 4.2.4 实现文件复制 1. 用文件流的 I/O 函数实现一个文件拷贝程序,将一个文件拷贝到另一个文件。 2. 分别用字节读,行读,任意大小读的方式。
- 关于二级指针的使用测试小例子,仅供测试--参数传递的时候用指针最好,因为压栈的时候指针,只是压入一个地址的值,最多4个字节(32位机上),提供的3个测试例子,基于VC6.0的环境。
- 算法导论10.2-8-用一个整数地址替代前后指针实现双向链表
- C#+MO实现一个道路编辑软件(刚开始)
- Linux下c语言实现将一个目录下的所有文件和目录复制到另一个目录下
- javascript实现获取、复制本页地址
- 使用指针复制字节数组
- exchange中实现一个用户邮箱拥有多个邮件地址
- 一个智能指针的实现(改进)
- QP实现之函数指针数组无法获取正确地址的问题
- 如何实现一个带引用记数的智能指针模板
- exchange中实现一个用户邮箱拥有多个邮件地址