设为首页 加入收藏

TOP

strcpy,memcpy,memmove和内存重叠分析 (一)
2014-11-23 19:22:25 来源: 作者: 【 】 浏览:9
Tags:strcpy memcpy memmove 内存 重叠 分析

一:strcpy函数用法和实现:
[cpp]
/*

 GNU-C中的实现(节选):

 */

 char* strcpy(char *d, const char *s)

 {

  char *r=d;

  while((*d++=*s++));

  return r;

 }

/*

 GNU-C中的实现(节选):

 */

 char* strcpy(char *d, const char *s)

 {

  char *r=d;

  while((*d++=*s++));

  return r;

 }
有没有发现这个实现并不是很好。。至少没有判断是不是为NULL。一个更好的版本:

[cpp]
char *strcpy(char *strDest, const char *strSrc)
{
assert((strDest!=NULL) && (strSrc !=NULL));
char *address = strDest;
while( (*strDest++ = * strSrc++) != '\0')

return address ;
}

char *strcpy(char *strDest, const char *strSrc)
{
assert((strDest!=NULL) && (strSrc !=NULL));
char *address = strDest;
while( (*strDest++ = * strSrc++) != '\0')

return address ;
}
好好研究这段代码其实写的挺妙的。。(当然不是我写的)。。

二:memcpy函数用法和实现:
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中

微软实现:

[cpp]
void * __cdecl memcpy (void * dst,const void * src, size_t count )
{
void * ret = dst;
#if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
{
extern void RtlMoveMemory( void *, const void *, size_t count );
RtlMoveMemory( dst, src, count );
}
#else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
/* * copy from lower addresses to higher addresses */
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
#endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
return(ret);
}

void * __cdecl memcpy (void * dst,const void * src, size_t count )
{
void * ret = dst;
#if defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC)
{
extern void RtlMoveMemory( void *, const void *, size_t count );
RtlMoveMemory( dst, src, count );
}
#else /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
/* * copy from lower addresses to higher addresses */
while (count--) {
*(char *)dst = *(char *)src;
dst = (char *)dst + 1;
src = (char *)src + 1;
}
#endif /* defined (_M_MRX000) || defined (_M_ALPHA) || defined (_M_PPC) */
return(ret);
}

写的是不是也很好。。仿佛天衣无缝啊!。。但是你有没有注意到一个问题:那就是内存重叠。。

什么叫内存重叠呢?就是两块内存区域有一个共同的部分。。是不是很SB的解释。。当存在这个问题的时候,那还和我们预期的那样拷贝吗?注意:理解了这个才是关键。。

例子:(引用网上一个例子)

[cpp]
int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
memcpy(a+4, a, sizeof(int)*6)

int a[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
memcpy(a+4, a, sizeof(int)*6) 如果照微软实现的话,那么输出应该是0123012301(理解这个再忘下看吧。。)

而我们想要达到的目的是输出:0123012345。。如果你实验一下,确实也是输出0123012345。。(对于这个问题,我也解释不了)。为了避免这样的情况发生,我们找到了一个更好的函数:memmove。。

三:memmove函数用法和实现
用法和memcpy函数一样。。

实现:

[cpp]
void *memmove(void *dest, const void *source, size_t count)
{
assert((NULL != dest) && (NULL != source));
char *tmp_source, *tmp_dest;
tmp_source = (char *)source;
tmp_dest = (char *)dest;
if((dest + count {// 如果没有重叠区域
while(count--)
*tmp_dest++ = *tmp_source++;
}
else
{ //如果有重叠(反向拷贝)
tmp_source += count - 1;
tmp_dest += count - 1;
while(count--)
*--tmp_dest = *--tmp;
}
return dest;
}

void *memmove(void *dest, const void *source, size_t count)
{
assert((NULL != dest) && (NULL != source));
char *tmp_source, *tmp_dest;
tmp_source = (char *)source;
tmp_dest = (char *)dest;
if((dest + count {// 如果没有重叠区域
while(count--)
*tmp_dest++ = *tmp_source++;

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU 4670 Cube number on a tree 下一篇简单概率dp-hdu-4487-Maximum Ran..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·C语言中,“指针”用 (2025-12-26 15:20:18)
·在c语言的指针运算中 (2025-12-26 15:20:15)
·C语言-函数指针与函 (2025-12-26 15:20:12)
·求navicat for mysql (2025-12-26 13:21:33)
·有哪位大哥推荐一下m (2025-12-26 13:21:30)