在memcpy函数中,如果源地址指向的地址不可用(指向了一个错误的地址),memcpy函数肯定会报错直到死机。有什么办法在memcpy函数中检测源地址是否是正确的?或者,如何保证memcpy函数不会死掉?再或者,有没有什么其他方法,实现在内存复制前,能够发现这个内存复制操作有可能会导致程序DIE

解决方案 »

  1.   

    memcpy这个函数是不安全,所以要求用户在用此函数时,要作好异常处理
    memcpy可能出现你说的那个错误,那么要用assert等函数确保原地址的正确
    你可以参考memcpy溢出原理的文章,来分析自己的程序
      

  2.   

    memcpy要拷贝的空间不是new出来的吗?写在try{}catch里面,并且空间不用的时候注意释放,并且空间指针的值为NULL
      

  3.   

    重载new delete malloc free等
    记录申请信息类似检测泄露程序
    memcpy的时候还要判断是否越界
    其实最主要的是良好的编码习惯
      

  4.   

    应该考虑通过好的上层设计来解决这一类问题吧。
      3. 坏指针,越界和指针的强制转换
      
          坏指针,越界和指针的强制转换往往是混在一起产生的。如果一个指针的内存结构被破坏了(被其他的代码以非正常的手段写过),那这个指针就被称为坏指针。坏指针的产生情况非常复杂,主要有:操作没有初始化的指针,越界操作内存,代码逻辑上的错误,指针强制转换越界。由于这几项的关连性太强,所以将其作为一个整体来说明:
      
          在使用memcpy, strcpy之类的函数的之前,最好作一个被Copy对象的内存越界检查以确保内存Copy操作不会引起越界问题。比如 memcpy(lpTarget,lpSource,size_t) 就要做三个检查:首先检查lpTarget是否合法,是不是为NULL,有没有指向其他内存区域;其次要看lpSource是否合法;最后检查lpSource可操作内存的长度是否小于Size_t,lpTarget的内存长度是否小于Size_t。这三个检查一个都不能忽略。虽然不见得一定要在代码中做检查,但是使用的时候心里要有数,不能没有搞清楚就去使用。一旦出现内存操作越界的问题,那这个程序就会当掉。比如Cstring类的内部保存字符串指针的地址是一直在变化的,这个时候要小心操作,不要直接使用那个一直在变化的指针。
      
          现在很多代码中都有强制转换指针类型的操作,比如LPBYTE转换成LPVOID。特别是在函数传参数的时候,经常需要做转换,但是那个转换是什么意思,一定要明白。比如转换指针类型之后,操作的内存空间是否会变化。 这个关键是基本数据类型是否熟悉的问题。 比如把一个LPBYTE指针转换成一个 char*,没有问题,两个的长度是相同的,都是一个byte。但如果把LPBYTE转换成一个 LPCTSTR,因为根据编码方式的不同,ANSI或者Unicode LPCTSTR的长度有时候是1个byte,有时候是2个byte。
      
          定义一个BYTE数组来保存一些个字符。那定义数组的Code要这样写:
      
      Temp = new BYTE[20*sizeof(TCHAR)];
      
      不然的话,有可能会出错。 对于一些专门操作string(以NULL结尾)的函数,比如 lstrlen,如果其操作对象是非String那么,依然有可能出错。实际上,最好是Code需要什么样的类型的指针就定义什么样类型的指针。这样就能减少很多的错误。 
            
          自定义的函数中如果需要传入一个数组指针,比如上面的Temp指针,只要不是基本数据类型的话,传入指针的同时一定要把数组的长度传入。只是评一个指针类型,是很难判断指针的buffer是多大的,除了string类型的指针。传入指针的buffer的长度在需要把这个指针作为返回值的时候是比较有用的,这样在函数里面做内存Copy,准备返回的时候,就能判断内存Copy是否会产生越界现象。另外如果传入一个指针,但是不准备回写,那请你把这个指针定义为const类型,这样在编译的时候就能知道有没有在写这个指针的内存buffer。注意这个只是一种减少出错的办法,但是不是完美的。毕竟在运行期,代码实际上可以操作任何内存空间的。==============================================不过,记得有个函数检查指针合法性的...记不起来了
      

  5.   

    问题解决了!谢谢大家啊
    通常,如果是在进行内存复制时,源地址是不可用的,在调试时,程序会中断在memcpy.asm中的下面一句
    rep movsd ;N - move all of our dwords
    为了避免这种情况的出现,可以使用下面的方法:
    __try
    {
    //访问内存地址0x000006
             memcpy(pbDup, (char*)0x000006,1000);  }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
    AfxMessageBox("内存复制出错了");
    }
      

  6.   

    MFC提供了一些函数来判断地址是否有效,如:AfxIsMemoryBlock,AfxIsString,AfxIsValidAddress。
      

  7.   

    用CMemoryState类来检测和捕捉内存异常 试试,不过好像越来越复杂了
      

  8.   

    // example for CMemoryState::CMemoryState
    // Includes all CMemoryState functions
    CMemoryState msOld, msNew, msDif;
    msOld.Checkpoint();
    CAge* page1 = new CAge( 21 );
    CAge* page2 = new CAge( 22 );
    msOld.DumpAllObjectsSince();
    msNew.Checkpoint();
    msDif.Difference( msOld, msNew );
    msDif.DumpStatistics();
      

  9.   

    死机?异常?可以考虑IsBad*这些函数。