strcpy,memcpy,memmove的内存重叠
2016-07-19 17:29
260 查看
1、strcpy不考虑内存重叠函数原型如下:
char *strcpy(char *strDest, const char *strSrc){
assert((strDest!=NULL) || (strSrc !=NULL));
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ ) ;
return address ;
}
2、memcpy在不考虑内存重叠的情况可以写成这样:
void* memcpy(void *dest, void *src, size_t size)
{
if(dest == nullptr || src == nullptr)
return nullptr;
void *result = dest;
while(size--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest+1;
src = (char*)src+1;
}
return result;
} 内存重叠是指拷贝源地址与目标地址发生重合。重叠从两方面考虑:
(1).dest数据覆盖了source; 如:dest(8byte) 地址:1000
source(8byte) 地址:1002
(2).dest所指的区域本来就是source的一部分; 如:dest(8byte) 地址:1000
source(8byte) 地址:0998
3、所以,在考虑重叠的情况下,应类似memove,改变memcpy
void *memcpy(void *dest, void *src, size_t size)
{
if(dest == nullptr || src == nullptr)
return nullptr;
void *result = dest;
if(dest < src || (char*)src+size < (char*)dest)//没有内存重叠
{
while(size--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest+1;
src = (char*)src+1;
}
}
else//有内存重叠
{
dest = (char*)dest+size-1;
src = (char*)src+size-1;
while(size--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest-1;
src = (char*)src-1;
}
}
return result;
}
char *strcpy(char *strDest, const char *strSrc){
assert((strDest!=NULL) || (strSrc !=NULL));
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ ) ;
return address ;
}
2、memcpy在不考虑内存重叠的情况可以写成这样:
void* memcpy(void *dest, void *src, size_t size)
{
if(dest == nullptr || src == nullptr)
return nullptr;
void *result = dest;
while(size--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest+1;
src = (char*)src+1;
}
return result;
} 内存重叠是指拷贝源地址与目标地址发生重合。重叠从两方面考虑:
(1).dest数据覆盖了source; 如:dest(8byte) 地址:1000
source(8byte) 地址:1002
(2).dest所指的区域本来就是source的一部分; 如:dest(8byte) 地址:1000
source(8byte) 地址:0998
3、所以,在考虑重叠的情况下,应类似memove,改变memcpy
void *memcpy(void *dest, void *src, size_t size)
{
if(dest == nullptr || src == nullptr)
return nullptr;
void *result = dest;
if(dest < src || (char*)src+size < (char*)dest)//没有内存重叠
{
while(size--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest+1;
src = (char*)src+1;
}
}
else//有内存重叠
{
dest = (char*)dest+size-1;
src = (char*)src+size-1;
while(size--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest-1;
src = (char*)src-1;
}
}
return result;
}
相关文章推荐
- 解决数据库连接池连接mysql时,每隔8小时mysql自动断开所有连接的问题
- Centos安装MongoDB
- 自我学习总结1:ajax实现编辑框的验证
- 上code之前的test plan
- oracle+关于"SP2-0618:+无法找到会话标识符。启用检查+PLUSTRACE+角色"错误
- 无器械健身锻炼全身肌肉的方法
- android图片压缩
- 9.Smarty的循环
- 通达OA 开发基于AJAX技术数据列表控件的智能表单(图文)
- 通达OA 开发基于AJAX技术数据列表控件的智能表单(图文)
- bootstrap禁用点击空白处关闭模态框
- Xcode操作SVN(高级部分)
- 源码分析-java-AbstractSequentialList
- 多线程脱离状态 + 调度
- caffe net implement
- npoi 删除行
- Paxos 算法浅析
- 阿里音乐流行趋势预测大赛 # 第一赛季第21名解决方案
- Android6.0以上 上传图片时 需要进行权限申请
- Android 玩转IOC,Retfotit源码解析,教你徒手实现自定义的Retrofit框架