1. 程式人生 > >C++ memset 和 memcpy

C++ memset 和 memcpy

(1) Memset

  原型:   extern void *memset(void *buffer, int c, int count);              

  用法:  #include <string.h>           

  功能: 把buffer所指記憶體區域的前count個位元組設定成字元 c。           

  說明: 返回指向buffer的指標。用來對一段記憶體空間全部設定為某個字元

  例如:     

   char a[10];                        

   memset(a, '\0', sizeof(a));               

memset可以方便的清空一個結構型別的變數或陣列。               

 如:

struct    _test{  char s[10];      

            int x;         

           int y;

 };        

變數     struct _test    st;              

(1)一般清空st的方法如下:

st.s[0] = '\0'; st.x =0;   st.y =0;               

(2) 用memset方法如下:               

 memset(&st,0,sizeof(struct _test));         

陣列:  struct _test     st[10];               

  memset(st,0,sizeof(struct _test)*10);  //清空方法

//memset 原始碼的實現 C語言

#include <mem.h>

void* memset(void* s, int c, size_t n)

{

     unsigned char* p = (unsigned char*) s;

     while (n > 0)

       {

               *p++ = (unsigned char) c;

                --n;

       }

      return s;

  }

 

 

(2)memcpy

 原型:extern void *memcpy(void*dest,void*src,unsignedintcount);            

 用法: #include <string.h>              

 功能: 由src所指記憶體區域複製count個位元組到dest所指記憶體區域。            

 說明: src和dest所指記憶體區域不能重疊,函式返回指向dest的指標.可以拿它拷貝任何資料型別的物件。   

例如:  

char a[10] ;              

 memcpy(b, a, sizeof(b));             /*注意如果用sizeof(a),會造成b的記憶體地址溢位*/

 

(3) Strcpy   

    原型: extern char *strcpy(char *dest,char *src);                  

    用法: #include <string.h>                    

    功能: 把src所指由NULL結束的字串複製到dest所指的陣列中。               

    說明: src和dest所指記憶體區域不可以重疊且dest必須有足夠的空間來容納 src的字串.返回指向dest的指標。                    

  例如:   

char a[100],b[50];

strcpy(a,b);

如用   strcpy(b,a);要注意a中的字串長度(第一個‘\0’之前)是否超過50位,如超過,則會造成b的記憶體地址溢位。

假如有如下程式碼,請問輸出為多少?

  #include "stdio.h"

  main() {  

            char dest[3];

            char str[6]="Hello";

            strcpy(dest,str);

             printf("%s\n",dest);

 }

 編譯輸出如下結果:

  Hello                  //沒有輸出亂碼,有點怪怪的為什麼?

分析:

             1>str中字串的長度大於dest 的記憶體長度3.為什麼str字串還能完拷貝到dest 中呢?

      來看看 strcpy的 原始碼實現:

char   *strcpy(char   *strDest,const   char   *strSrc)   

{   

        assert((strDest!=NULL)&&(strSrc   !=NULL))   //判斷指標是否合法,即分配記憶體,指向某塊確定區域

        char   *address   =   strDest;               //記住目標地址的起始值

        while((*strDest++   =   *strSrc++)!='\0')   //先拷貝,後判斷,這樣就不用在拷貝完了後,再加一句  NULL;             

     // *strDest = '\0'; -->即加一個結束符.因為字串結束已拷貝了.

       return   address;      //返回目標首地址的值。            

 }

        //從上面的程式碼可以看出,strcpy函式,假定strDest的記憶體空間是足夠可以放下strSrc的內容的.

        //也就是說使用者,在使用strcpy函式時,應使 (strDest記憶體空間)>=  (strSrc記憶體空間)     

        // 在呼叫   strcpy(dest,str);  時,while((*strDest++   =   *strSrc++)!='\0')   沒有判斷strDest的記憶體是否夠,而是將srtSrc的內容直接拷貝到strDest,當拷到'\0'就結束.

        //因此在使用printf("%s\n",dest);  時 輸出遇到'\0'時停此輸出.所以會輸出: Hello

 

 (4) 三者區別                    

           memset   主要應用是初始化某個記憶體空間。                  

           memcpy   是用於copy源空間的資料到目的空間中。                  

           strcpy   用於字串copy,遇到‘\0’,將結束。                  

如果理解了這些,就能知道它們的區別:                 

 例如初始化某塊空間的時候,用到memcpy,那麼就顯得笨拙                 

    int    m[100]                     

   memset((void*)m,0x00,sizeof(int*100);             //Ok!                     

   memcpy((void*)m,"\0\0\0\0....",sizeof(int)*100);    //Not Ok

 

*******函式原型*******   

 1、   strcpy    extern char *strcpy(char *dest,char *src);   

    #include <string.h>   

   功能:把src所指由NULL結束的字串複製到dest所指的陣列中   

   說明:  src和dest所指記憶體區域不可以重疊且dest必須有足夠的空間來容納src的字串。   返回指向dest的指標   

 

   2、 memcpy   extern void *memcpy(void *dest,void *src,unsigned int count);  

    #include <string.h>   

    功能:由src所指記憶體區域複製count個字串到dest所指記憶體區域.   

    說明:src和dest所指記憶體區域不能重疊,函式返回指向dest的指標.      

 

  3、  memset    extern void *memset(void *buffer,int c,int count);   

    #include <string.h>   

    功能:把buffer所指記憶體區域的前count個位元組設定成字元c   

   說明:返回指向buffer的指標.

 

*******區別   ****************

1)memset 用來對一段記憶體空間全部設定為某個字元,一般用於在對定義的字串初始化為' '或者'\0';     

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

2)memcpy 是用來做記憶體拷貝,可以用來拷貝任何資料型別的物件,可以指定拷貝的資料長度;   

             例:       char a[100],b[50];            

                       memcpy(b,a,sizeof(b));   

   //注意:如果使用sizeof(a),會造成記憶體溢位            

   mem是一段記憶體,他的長度,必須自己記住.memcpy是見著什麼拷貝什麼。         

3)strcpy 就只能拷貝字串,它遇到'\0'就結束拷貝;      

            例:char a[100],b[50];               strcpy(a,b);              

            如用strcpy(b,a)要注意a中的字串長度(第一個'\0'之前) 是否超過50,如果超過,則會造成b的   記憶體溢位.

      它是不會拷貝'\0'的,所以一般還有加一個語句:               *a='\0';   

 

************使用技巧  ************************

 

  memset 可以方便的清空一個數據結構的變數或陣列.      

        如:         struct sample_struct  {  

                                  char   csName[16];               

                                  int      iSeq;              

                                  int       iType;        

                                    };        

       對於變數        

        struct sample_struct   stTest;        

                一般情況下,初始化stTest的方法:         

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

                         stTest.iSeq=0;         

                         stTest.iType=0;     

         而用memset:        

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

                    如果是陣列:     

                     struct sample_struct   TEST[100];     

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