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只能複製
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來初始化的。