1. 程式人生 > >mem家族(memset和memcpy)

mem家族(memset和memcpy)

1. mem開頭的函式基本上都是對記憶體操作的,

    它們不管記憶體裡放的是什麼資料,只要給出長度,它們就操作。不像strcpy、strcmp等函式一定以'\0'結尾,而且是字元。mem可以操作可見字元、不可見字元、控制字元等,任意資料都可以。

2. memcpy是記憶體複製函式

    原型: 

       void * memcpy(void *dest, void const *src, unsigned intlength); 

    功能:從src的起始位置複製length個位元組到dst的記憶體起始位置。你可以用這種方法複製任何型別的值,第3個引數指定複製值的長度(以位元組計用sizeof())。

       如果src和dst以任何形式出現了重疊,它的結果是未定義的。

 3. memset函式

     原型:

void * memset(void *a, int val, unsignedint length);

     功能:把從a開始的length個位元組都設定為值val。

     例子:memset(buffer, 0, SIZE);

Memcpy詳解:

結構如下:void *memcpy(void *dest, const void *src,size_t count);

作用:在dest處拷貝src處的位元組,並以count來計算需要拷貝的位元組數量,進行記憶體的拷貝。

引數:dest:新的存貯區的開始部位   src:需要拷貝的開始部位   count:需要拷貝的位元組數

備註:dest,src,它們都是從各自的地址處進行寫入,如果是p而不是&p,那麼獎會取得p的值(地址),在該值的地址處進行讀出或寫入.

memcpy函式的特點是:
       1. 使用memcpy函式前,實參dest必須初始化,否則可能會出錯。
       2. 函式原理是將void *src 強制轉換為char *s,然後只負責拷貝n個位元組到dest裡,不負責在最後加上'\0'。

strcpy和memcpy主要有以下3方面的區別。

1、複製的內容不同。strcpy只能複製

字串,而memcpy可以複製任意內容,例如字元陣列、整型、結構體、類等。

2、複製的方法不同。strcpy不需要指定長度,它遇到被複制字元的串結束符"\0"才結束,所以容易溢位。memcpy則是根據其第3個引數決定複製的長度。

3、用途不同。通常在複製字串時用strcpy,而需要複製其他型別資料時則一般用memcpy

memset詳解:

void * memset(void*s, int ch, size_t n);

memset:其實是給一段記憶體初始化。作用是在一段記憶體塊中填充某個給定的值,它是對較大的結構體陣列進行清零操作的一種最快方法(注意:memset是以位元組為單位,初始化記憶體塊。)

函式解釋:將s記憶體中前n個位元組並用 ch 替換,該函式返回 s的指標 。

1.為什麼要使用memset清零?答:如果不清空,可能會在測試當中出現野值。

2.memset() 函式常用於記憶體空間初始化。如:
           charstr[100];
           memset(str,0,100*sizeof(char));

       char data[10];  

memset(data, 0, sizeof(data));    // right  

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

          如:
           structsample_struct{
                     char csName[16];
                      int iSeq;
                      int iType;
           };

          對於變數:
           structsample_strcut stTest;

          一般情況下,清空stTest的方法:
           stTest.csName[0]='/0';
           stTest.iSeq=0;
           stTest.iType=0;

          用memset就非常方便:
          memset(&stTest,0,sizeof(struct sample_struct));

4.  當結構體型別中包含指標時,在使用memset初始化時需要小心。

比如如下程式碼中,

struct Parameters {  

               int x;  

                int* p_x;  

};  

Parameters par;  

par.p_x = new int[10];  

memset(&par, 0, sizeof(par));  

當memset初始化時,並不會初始化p_x指向的int陣列單元的值,而會把已經分配過記憶體的p_x指標本身設定為0,造成記憶體洩漏。同理,對std::vector等資料型別,顯而易見也是不應該使用memset來初始化的。