void *memset(void *s, int ch, size_t n);(int ch可以是char或int)
將s所指向的某一塊內存中的每個字節的內容全部設置為ch指定的ASCII值, 塊的大小由第三個參數指定,這個函數通常為新申請的內存做初始化工作, 其返回值為指向S的指針。
memset按字節賦值。
需要的頭文件
在C中 <string.h>
在C++中 <cstring>
void *memset(void *s, int ch, size_t n);
函數解釋:將s中前n個字節 (typedef unsigned int size_t)用 ch 替換並返回 s 。
常見錯誤
第一: 搞反了 ch 和 n 的位置.
一定要記住如果要把一個char a[20]清零,一定是 memset(a,0,20);
而不是 memset(a,20,0);
第二: 過度使用memset,我想這些
程序員可能有某種心理陰影,他們懼怕未經初始化的內存,所以他們會寫出這樣的代碼:
char
buffer[20];
memset
(buffer,0,
sizeof
(
char
)*20);
strcpy
(buffer,
"123"
);
這里的
memset是多余的. 因為這塊內存馬上就被覆蓋了,清零沒有意義.
第三: 其實這個錯誤嚴格來講不能算用錯memset,但是它經常在使用memset的場合出現
int some_func(struct something *a) { … … memset(a,0,sizeof(a)); … }
常見問題
問:為何要用memset置零?memset(&Address,0,sizeof(Address));經常看到這樣的用法,其實不用的話,分配數據的時候,剩余的空間也會置零的。
答:1.如果不清空,可能會在測試當中出現野值。你做下面的試驗看看結果()
#include "iostream.h" #include "string.h" #include <afx.h> int main(){ char buf[5]; CString str; CString str1; CString str2; memset(buf,0,sizeof(buf)); for(int i = 0; i<5; i++){ str.Format("%d",buf[i]); str1 +=str ; } str2.Format("%d",str1); cout<<str2<<endl; system("pause"); return 0; }
這樣寫,有沒有memset,輸出都是一樣
⒉其實不然!特別是對於字符指針類型的,剩余的部分通常是不會為0的,不妨作一個
試驗,定義一個字符
數組,並輸入一串字符,如果不用memset實現清零,使用MessageBox顯示出來就會有亂碼(0表示NULL,如果有,就默認字符結束,不會輸出后面的亂碼)
問:
include <iostream> #include <cstring> using namespace std; int main(){ char a[5]; memset(a,'1',5); for(int i = 0;i < 5;i++) cout<<a[i]<<" "; system("pause"); return 0; }
而,如下程序想把數組中的元素值設置成1,卻是不可行的
#include <iostream> #include <cstring> #include <windows.h> using namespace std; int main() { int a[5]; memset(a,1,20);//如果這里改成memset(a,1,5*sizeof(int))也不可以,因為memset按字節賦值。 for(int i = 0;i < 5;i++) cout<<a[i]<<" "; system("pause"); return 0; }
問題是:
1,第一個程序為什么可以,而第二個不行?
因為第一個程序的數組a是字符型的,字符型占據內存大小是1Byte,而memset函數也是以字節為單位進行賦值的,所以你輸出沒有問題。而第二個程序a是整型的,使用 memset還是按
字節賦值,這樣賦值完以后,每個
數組元素的值實際上是0x01010101即十進制的16843009。
2,不想要用for,或是while循環來初始化int a[5];能做到嗎?(有沒有一個像memset()這樣的函數初始化)
如果用memset(a,1,20);(實際上與memset(a,1,5*sizeof(int))結果是一樣的)就是對a指向的內存的20個
字節進行賦值,每個都用ASCⅡ為1的字符去填充,轉為二進制后,1就是00000001,占一個字節。一個INT元素是4
字節,
合一起就是0x01010101(十六進制),就等於16843009,就完成了對一個INT元素的賦值了。
所以用memset對非字符型數組賦初值是不可取的!
怎么對bool型數組賦值:
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就非常方便: 1 memset(&stTest,0,sizeof(struct sample_struct)); 如果是數組: struct sample_struct TEST[10]; 則 memset(TEST,0,sizeof(struct sample_struct)*10); 另外: 如果結構體中有數組的話還是需要對數組單獨進行初始化處理的。
來自百度百科。http://baike.baidu.com/view/982208.htm