將s所指向的某一塊內(nèi)存中的前n個(gè)字節(jié)的內(nèi)容全部設(shè)置為ch指定的ASCII值, 第一個(gè)值為指定的內(nèi)存地址,塊的大小由第三個(gè)參數(shù)指定,這個(gè)函數(shù)通常為新申請(qǐng)的內(nèi)存做初始化工作, 其返回值為指向s的指針
void *memset(void *s, int ch, size_t n);
函數(shù)解釋:將s中當(dāng)前位置后面的n個(gè)字節(jié) (typedef unsigned int size_t )用 ch 替換并返回 s 。
memset:作用是在一段內(nèi)存塊中填充某個(gè)給定的值,它是對(duì)較大的結(jié)構(gòu)體或數(shù)組進(jìn)行清零操作的一種最快方法。
常見(jiàn)錯(cuò)誤
- memset函數(shù)按字節(jié)對(duì)內(nèi)存塊進(jìn)行初始化,所以不能用它將int數(shù)組初始化為0和-1之外的其他值(除非該值高字節(jié)和低字節(jié)相同)。
- memset(void s, int ch,size_tn);中key實(shí)際范圍應(yīng)該在0~~255,因?yàn)樵摵瘮?shù)只能取ch的后八位賦值給你所輸入的范圍的每個(gè)字節(jié),比如int a[5]賦值memset(a,-1,sizeof(int )5)與memset(a,511,sizeof(int )*5) 所賦值的結(jié)果是一樣的都為-1;因?yàn)?1的二進(jìn)制碼為(11111111 11111111 11111111 11111111)而511的二進(jìn)制碼為(00000000 00000000 00000001 11111111)后八位都為(11111111),所以數(shù)組中每個(gè)字節(jié),如a[0]含四個(gè)字節(jié)都被賦值為(11111111),其結(jié)果為a[0](11111111 11111111 11111111 11111111),及a[0]=-1,因此無(wú)論ch多大只有后八位二進(jìn)制有效,而八位二進(jìn)制[2] 的范圍(0~255)YKQ改。而對(duì)字符數(shù)組操作時(shí)則取后八位賦值給字符數(shù)組,其八位值作為ASCII[3] 碼。
- 搞反了 ch 和 n 的位置.
一定要記住如果要把一個(gè)char a[20]清零,一定是 memset(a,0,20*sizeof(char));
而不是 memset(a,20*sizeof(char),0);
- 過(guò)度使用memset,我想這些程序員可能有某種心理陰影,他們懼怕未經(jīng)初始化的內(nèi)存,所以他們會(huì)寫(xiě)出這樣的代碼:
char buffer[4];
memset(buffer, 0, sizeof`(char)*4);
strcpy(buffer, "123");
//"123"中最后隱藏的'\0'占一位,總長(zhǎng)4位。
這里的memset是多余的. 因?yàn)檫@塊內(nèi)存馬上就被全部覆蓋,清零沒(méi)有意義.
另:以下情況并不多余,因某些編譯器分配空間時(shí),內(nèi)存中默認(rèn)值并不為0:
char buffer[20];
memset(buffer, 0, sizeof(char)*20);
memcpy(buffer, "123", 3);
//這一條的memset并不多余,memcpy并沒(méi)把buffer全部覆蓋,如果沒(méi)有memset,
//用printf打印buffer會(huì)有亂碼甚至?xí)霈F(xiàn)段錯(cuò)誤。
//如果此處是strcpy(buffer,"123");便不用memset,
//strcpy雖然不會(huì)覆蓋buffer但是會(huì)拷貝字符串結(jié)束符
- 其實(shí)這個(gè)錯(cuò)誤嚴(yán)格來(lái)講不能算用錯(cuò)memset,但是它經(jīng)常在使用memset的場(chǎng)合出現(xiàn)
int some_func(struct something *a)
{
…
…
memset(a,0,sizeof(a));
…
}
這里錯(cuò)誤的原因是VC函數(shù)傳參過(guò)程中的指針降級(jí),導(dǎo)致sizeof(a),返回的是一個(gè)something指針類型大小的字節(jié)數(shù)*,如果是32位,就是4字節(jié)。
參考百度百科詞條