最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

memmove、memcpy、memset、strcpy四者的区别

来源:动视网 责编:小OO 时间:2025-09-30 08:25:43
文档

memmove、memcpy、memset、strcpy四者的区别

C/C++:memmove、memcpy、strcpy三者的区别以及memset,memcpy和strcpy的根本区别转:C/C++:memmove、memcpy、strcpy三者的区别strcpy只能处理字符串;如果拷贝带有特殊字符的串,就只能用memcpy或memmove。memcpy和memmove功能基本上差不多,但是当源串和目标串有Overlap时,memmove可以正确处理,memcpy则不行。  memcpy()和memmove()都是C语言中的库函数,在头文件string.h中
推荐度:
导读C/C++:memmove、memcpy、strcpy三者的区别以及memset,memcpy和strcpy的根本区别转:C/C++:memmove、memcpy、strcpy三者的区别strcpy只能处理字符串;如果拷贝带有特殊字符的串,就只能用memcpy或memmove。memcpy和memmove功能基本上差不多,但是当源串和目标串有Overlap时,memmove可以正确处理,memcpy则不行。  memcpy()和memmove()都是C语言中的库函数,在头文件string.h中
C/C++:memmove、memcpy、strcpy三者的区别 以及memset ,memcpy 和strcpy 的根本区别

 转:C/C++:memmove、memcpy、strcpy三者的区别 

strcpy只能处理字符串;如果拷贝带有特殊字符的串,就只能用memcpy或memmove。memcpy和memmove功能基本上差不多,但是当源串和目标串有Overlap时,memmove可以正确处理,memcpy则不行。

 

 

memcpy()和memmove()都是C语言中的库函数,在头文件string.h中,其原型分别如下: 

 

void *memcpy(void *dst, const void *src, size_t count);

void *memmove(void *dst, const void *src, size_t count

);
 

它们都是从src所指向的内存中复制count个字节到dst所指内存中,并返回dst的值。当源内存区域和目标内存区域无交叉时,两者的结果是一样的,但如果有交叉呢?先看下图:

 

图的上半部分为源内存区域在目标内存区域右边,下半部分为源内存区域在目标区域左边,源内存区域和目标内存区域都有交叉。

memcpy()是从src的起始部分开始复制,所以虽然第一种情况下没有问题,但如果遇到第二种情况,则会发生错误,如图所示,后两个字节在被复制前已经被覆盖掉了。而memmove()则由于采用了不同的复制机制,所以可以正确处理第二种情况。

VS.NET2003中所附源码如下(有删):

void * __cdecl memcpy (void * dst, const void * src, size_t count)

{

        void * ret = dst;

        

        while (count--) {

                *(char *)dst = *(char *)src;

                dst = (char *)dst + 1;

                src = (char *)src + 1;

        }

        return(ret);

}

void * __cdecl memmove (void * dst, const void * src, size_t count)

{

        void * ret = dst;

        if (dst <= src || (char *)dst >= ((char *)src + count)) {

                

                while (count--) {

                        *(char *)dst = *(char *)src;

                        dst = (char *)dst + 1;

                        src = (char *)src + 1;

                }

        }

        else {

                

                dst = (char *)dst + count - 1;

                src = (char *)src + count - 1;

                while (count--) {

                        *(char *)dst = *(char *)src;

                        dst = (char *)dst - 1;

                        src = (char *)src - 1;

                }

        }

        return(ret);

}

strcpy只能处理字符串;如果拷贝带有特殊字符的串,就只能用memcpy或memmove。memcpy和memmove功能基本上差不多,但是当源串和目标串有Overlap时,memmove可以正确处理,memcpy则不行。

memcpy()和memmove()都是C语言中的库函数,在头文件string.h中,其原型分别如下: 

  

void * memcpy ( void * dst, const void * src, size_t count) ; 

void * memmove ( void * dst, const void * src, size_t count) ; 

 

  

它们都是从src所指向的内存中复制count个字节到dst所指内存中,并返回dst的值。当源内存区域和目标内存区域无交叉时,两者的结果是一样的,但如果有交叉呢?先看下图: 

  

 

图的上半部分为源内存区域在目标内存区域右边,下半部分为源内存区域在目标区域左边,源内存区域和目标内存区域都有交叉。 

memcpy()是从src的起始部分开始复制,所以虽然第一种情况下没有问题,但如果遇到第二种情况,则会发生错误,如图所示,后两个字节在被复制前已经被覆盖掉了。而memmove()则由于采用了不同的复制机制,所以可以正确处理第二种情况。 

VS.NET2003中所附源码如下(有删): 

void * __cdecl memcpy ( void * dst, const void * src, size_t count ) 

        void * ret = dst; 

         

        while ( count - - ) { 

                * ( char * ) dst = * ( char * ) src; 

                dst = ( char * ) dst + 1; 

                src = ( char * ) src + 1; 

        } 

        return ( ret) ; 

 

void * __cdecl memmove ( void * dst, const void * src, size_t count ) 

        void * ret = dst; 

if ( dst < = src | | ( char * ) dst > = ( ( char * ) src + count ) ) {

                 

                while ( count - - ) { 

                        * ( char * ) dst = * ( char * ) src; 

                        dst = ( char * ) dst + 1; 

                        src = ( char * ) src + 1; 

                } 

        } 

        else { 

                 

                dst = ( char * ) dst + count - 1; 

                src = ( char * ) src + count - 1; 

                while ( count - - ) { 

                        * ( char * ) dst = * ( char * ) src; 

                        dst = ( char * ) dst - 1; 

                        src = ( char * ) src - 1; 

                } 

        } 

        return ( ret) ; 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jiang1013nan/archive/2009/12/26/5073116.aspx

void* mymemcpy(void* pvTo, const char* pvFrom, size_t size)

{

     assert((dest != NULL) && (src != NULL));

     byte* psTo = (byte*)pvTo;

     byte* psFrom = (byte*)pvFrom;

while (size-- > 0)

     {

         *psTo++ = *psFrom++;

     }

     return pvTo;

}

memset ,memcpy 和strcpy 的根本区别

2009年10月27日 星期二 上午 10:46

以下内容为网络整理的结果!

它们用处不同,但大部分情况下可以完成相同的要求。

strcpy

原型:extern char *strcpy(char *dest,char *src); 用法:#include 功能:把src所指由NULL结束的字符串复制到dest所指的数组中。说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。返回指向dest的指针。

例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘\\0’之前)是否超过50位,如超过,则会造成b的内存地址溢出。

memcpy 原型:extern void *memcpy(void *dest, void *src, unsigned int count);用法:#include 功能:由src所指内存区域复制count个字节到dest所指内存区域。说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。可以拿它拷贝任何数据类型的对象。

举例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。

memset原型:extern void *memset(void *buffer, int c, int count);用法:#include 功能:把buffer所指内存区域的前count个字节设置成字符c。说明:返回指向buffer的指针。用来对一段内存空间全部设置为某个字符。

举例:char a[100];memset(a, '\\0', sizeof(a));

memset可以方便的清空一个结构类型的变量或数组。

如:

struct sample_struct

{

char csName[16];

int iSeq;

int iType;

};

对于变量

struct sample_strcut stTest;

一般情况下,清空stTest的方法:

stTest.csName[0]='\\0';

stTest.iSeq=0;

stTest.iType=0;

用memset就非常方便:

memset(&stTest,0,sizeof(struct sample_struct));

如果是数组:

struct sample_struct TEST[10];则

memset(TEST,0,sizeof(struct sample_struct)*10);

对这个问题有疑问,不是对函数的疑问,而是因为没有弄懂mem和str的区别。

mem是一段内存,他的长度,必须你自己记住

str也是一段内存,不过它的长度,你不用记,随时都可以计算出来所以memcpy需要第三个参数,而strcpy不需要

void* memcpy(void* pvTo, const void* pvForm, size_t size)

{

assert((pvTo!= NULL) && (pvFrom!= NULL));//使用断言防止传递空地址

unsigned char* pbTo = (unsigned char*)pvTo;//防止改变pvTo的地址

unsigned char* pbFrom = (unsigned char*)pvFrom;//防止改变pvFrom的地址

while(size-- > 0)

{

   *pbTo++ = *pbFrom++;

}

return pvTo;

}

char* strcpy(char* pDest, const char* pSrc)

{

assert((pDest != NULL) && (pSrc != NULL));

char *pTmp = pDest;

while ((*pDest++ = *pSrc++) != '\\0')

   ;

return pTmp;

}

FeedBack:

# re: memcpy与strcpy实现

2008-08-27 20:35 | temp

do not forget const  

  

# re: memcpy与strcpy实现

2009-07-23 22:10 | flame

//注意数据重叠区的处理。 

// |----------| 

// |----------| 

void *MyMemCopy(void *dest,const void *src,size_t count) 

char *pDest=static_cast(dest); 

const char *pSrc=static_cast(src); 

//注意,这里是关键,为什么要这样比较呢?理由何在? 

if( pDest>pSrc && pDest

for(size_t i=count-1; i>=0; --i) 

pDest[i]=pSrc[i]; 

else 

for(size_t i=0; i

pDest[i]=pSrc[i]; 

return pDest; 

}

//注意数据重叠区的处理。 

// |----------| 

// |----------| 

void *MyMemCopy(void *dest,const void *src,size_t count) 

char *pDest=static_cast(dest); 

const char *pSrc=static_cast(src); 

//注意,这里是关键,为什么要这样比较呢?理由何在? 

if( pDest>pSrc && pDest

for(size_t i=count-1; i>=0; --i) 

pDest[i]=pSrc[i]; 

else 

for(size_t i=0; i

pDest[i]=pSrc[i]; 

return pDest; 

}

这篇文章里的内容就是对那些想通过自我研究达到学会编程目的的新手们的一些重要建议。 编程老手们:我有什么遗漏吗? 不论你的水平如何,请留下你的想法。

文档

memmove、memcpy、memset、strcpy四者的区别

C/C++:memmove、memcpy、strcpy三者的区别以及memset,memcpy和strcpy的根本区别转:C/C++:memmove、memcpy、strcpy三者的区别strcpy只能处理字符串;如果拷贝带有特殊字符的串,就只能用memcpy或memmove。memcpy和memmove功能基本上差不多,但是当源串和目标串有Overlap时,memmove可以正确处理,memcpy则不行。  memcpy()和memmove()都是C语言中的库函数,在头文件string.h中
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top