前段时间准备面试,看了一些库函数的实现,在看到memcpy时,发现有处理source和destination所指内存有重叠的情况,而strcpy没有,特别模仿库函数写了这个函数,并进行了测试.以下是具体的source code 和测试结果.
 
char *strcpy2(char *strDest, const char *strSrc)
{
assert( (strDest!=NULL) && ( strSrc!=NULL));
 if ( strDest == strSrc)
  return strDest ;
 char *tempptr = strDest ;
while( (*strDest++ = *strSrc++) != '\0')
;
return tempptr ;
}
这是修改网络上source code得到的一个版本,简洁,完全可以工作.初看觉得在程序内部改变了strDest和strSrc的地址(确实如此),不是太好,而实际上当别的函数调用后strDest和strSrc的地址恢复到调用前,因为调用只是改变参数的副本,程序改变地址指向的内容,而没有改变地址本身.不过更加明了的写法是用两个零时变量来替代,修改后如下:
char *strcpy3(char *strDest, const char *strSrc)
{
assert( (strDest!=NULL) && ( strSrc!=NULL));
 if ( strDest == strSrc)
   return strDest ;
 char *pDest = strDest ;
 char *pSrc=\'#\'" /> while( (*pDest ++ = *pSrc ++) != '\0');
 return strDest;
}
和strcpy2相比,增加了一个变量,不过程式更清晰,看个人爱好了.我偏向strcpy3.呵呵.
 
void memcpy2(void *pDst,const void *pSrc, size_t size)
{
 assert(pDst != NULL);
 assert(pSrc != NULL);
 //src and dst has a  shared area.
 if((pSrc<pDst) && ((char*)pSrc+size > pDst))
 {
  char *pstrSrc= (char *)pSrc + size -1;
  char *pstrDst = (char *)pDst + size -1;
while(size--)
   *pstrDst -- = *pstrSrc--;
 }
 else
 {
  char *pstrSrc= (char *)pSrc ;
  char *pstrDst = (char *)pDst ;
while(size--)
   *pstrDst++ = *pstrSrc++;
 }
}
 
 
int main()
{
 char *pSrc = (char *)malloc(1024);
 char *pDst = pSrc+4;
 strcpy2(pSrc,"12345678910");
 strcpy2(pDst,pSrc);    //(1)
 printf("Before memcpy: pSrc =%s pDst =%s\n",pSrc,pDst);
 memcpy2(pDst,pSrc,strlen(pSrc)*sizeof(char));
 printf("After memcpy: pSrc =%s \n pDst =%s\n",pSrc,pDst);
 return 0;
}
 
测试结果:
1.如果没有注释掉语句(1),执行到词语时,因为pDst覆盖了pSrc的结束符'\0'而陷入死循环,最后访问到不该访问的地址空间而出现debug错误.
2.注释掉语句(1),执行 memcpy2后,pSrc变成"123412345678910########",pDst变成"12345678910####","#"表示乱码,原因也是原有的结束符被覆盖.程序可以结束.
 
 
总结:
 1.const在特定的情况下并不能保证它所修饰函数参数为只读.
 2.在内存块有重叠的情况下,strcpy会崩溃,memcpy不会.

strcpy,memcpy,内存块重叠的更多相关文章

  1. 字符串函数(strcpy字符串拷,strcmp字符串比较,strstr字符串查找,strDelChar字符串删除字符,strrev字符串反序,memmove拷贝内存块,strlen字符串长度)

    1.strcpy字符串拷贝拷贝pStrSource到pStrDest,并返回pStrDest地址(源和目标位置重叠情况除外) char *strcpy(char *pStrDest, const ch ...

  2. C语言memmove()函数: 复制内存内容(可以重叠的内存块)

    头文件:#include <string.h> memmove() 用来复制内存内容,其原型为: void * memmove(void *dest, const void *src, s ...

  3. strcpy, memcpy, memset函数

    一. strcpy函数 原型声明:char *strcpy(char* dest, const char *src);   头文件:#include <string.h> 和 #inclu ...

  4. C++实现简单的内存块自己主动管理

    #ifndef __MEM__H #define __MEM__H #include<iostream> using namespace std; //自己主动管理内存块 typedef ...

  5. strcpy函数内存分析

    void strcpy(char* strDest, char* strSrc) { while((*strDest++ = *strSrc++) != '\0'); } 看上面这段代码,只有一条语句 ...

  6. Python解析器源码加密系列之(二):一次使用标准c的FILE*访问内存块的尝试

    摘要:由于近期打算修改Python解释器以实现pyc文件的加密/解密,出于保密的要求,解密之后的数据只能放在内存中,不能写入到文件中.但是后续的解析pyc文件的代码又只能接受FILE*作为入参,所以就 ...

  7. memcpy内存拷贝及优化策略图解

    一般内存拷贝与优化 代码实现 #include<iostream> usingnamespace std; //不安全的内存拷贝(当源内存地址与目标内存地址重叠时会产生错误) void h ...

  8. 固定尺寸内存块的缓冲队列类及C++实现源代码

    -------------------------------------------------------------------------------- 标题: 固定尺寸内存块的缓冲队列类及实 ...

  9. access_ok | 检查用户空间内存块是否可用

    access_ok() 函数是用来代替老版本的 verify_area() 函数的.它的作用也是检查用户空间指针是否可用. 函数原型:access_ok (type, addr, size); 变量说 ...

随机推荐

  1. [翻译][MVC 5 + EF 6] 2:基础的增删改查(CRUD)

    原文:Implementing Basic CRUD Functionality with the Entity Framework in ASP.NET MVC Application 1.修改Vi ...

  2. Android学习5—布局简介

    Android界面的布局主要有四种,分别为RelativeLayout.LinearLayout.TableLayout.FrameLayout,接下来分别介绍这些布局如何使用(为了简单起见,接下来的 ...

  3. varchar(n),nvarchar(n) 长度、性能、及所占空间分析 nvarchar(64) nvarchar(128) nvarchar(256)(转)

    varchar(n),nvarchar(n) 中的n怎么解释: nvarchar(n)最多能存n个字符,不区分中英文. varchar(n)最多能存n个字节,一个中文是两个字节. 所占空间: nvar ...

  4. Python3 字符编码

    编码 字符串是一种数据类型,但是,字符串比较特殊的是还有一个编码问题. 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.最早的计算机在设计时采用8个比特(bit)作为一个字节 ...

  5. Spring Cloud Eureka Server 启停状态监控

    目前发现如下的api: 当时没有找到文档 http://localhost:8761/eureka/apps 参考文章:(此文中api带有v2我自己试验不需要v2) http://blog.csdn. ...

  6. mvc中的OutputCache

    mvc4中有一个标记属性OutputCache,用来对ActionResult结果进行缓存,如何理解呢?概括地说,就是当你的请求参数没有发生变化时,直接从缓存中取结果,不会再走服务端的Action代码 ...

  7. smarty

    模板引擎是用于把模板文件和数据内容合并在一起的程序,便于网站开发有利于代码分离和维护,了解一个模板最好知道其工作原理,以便于实现一通万通. 模板文件一般是HTML xml js等类型文件,如果不用模板 ...

  8. python之PIL安装问题

    ··在windows安装模块 总是出现问题,今天安装PIL的 首先提示我的是pip命令出错,这应该是当你安装Python2.7的时候 并没有把pip模块添加进去 导致出现了这样的一个问题,为了省事,我 ...

  9. Python httpsqs封装类

    ''' httpsqs队列封装 @author xp_go@qq.com a = HttpsqsClient('192.168.0.218','1218','httpsqsmmall.com') pr ...

  10. NET Portability Analyzer

    NET Portability Analyzer 分析迁移dotnet core 大多数开发人员更喜欢一次性编写好业务逻辑代码,以后再重用这些代码.与构建不同的应用以面向多个平台相比,这种方法更加容易 ...