http://www.jb51.net/article/71577.htm
2015
頭文件:
memset() 函數用來(lái)將指定內存的前n個(gè)字節設置為特定的值,其原型為:
參數說(shuō)明:
ptr 為要操作的內存的指針。
value 為要設置的值。你既可以向 value 傳遞 int 類(lèi)型的值,也可以傳遞 char 類(lèi)型的值,int 和 char 可以根據 ASCII 碼相互轉換。
num 為 ptr 的前 num 個(gè)字節,size_t 就是unsigned int。
【函數說(shuō)明】memset() 會(huì )將 ptr 所指的內存區域的前 num 個(gè)字節的值都設置為 value,然后返回指向 ptr 的指針。
memset() 可以將一段內存空間全部設置為特定的值,所以經(jīng)常用來(lái)初始化字符數組。例如:
【返回值】返回指向 ptr 的指針。
注意:參數 value 雖聲明為 int,但必須是 unsigned char,所以范圍在0 到255 之間。
范例:
1 2 3 4 5 6 7 8 9 10 11 12 | #include <stdio.h>#include <stdlib.h>#include <string.h>int main(){ memset(str, '-', 7); puts(str); system("pause"); return EXIT_SUCCESS;} |
執行結果:
優(yōu)化:盡量用memset將一個(gè)數組設置清零(帶虛類(lèi)除外),而不是通過(guò)for循環(huán)逐個(gè)置0
下面這個(gè)例子,大家可以參考:3D游戲編程大師技巧。本文其實(shí)重點(diǎn)是memset,原因是在工作中,用的比較多。
例如:要清空一個(gè)float f[10000],應該用memset(f,0,sizeof(float) * 10000);
而不是: for(int i=0; i<10000; ++i) f[i] = 0;
當然,還可以用內嵌匯編的形式:
哈,這個(gè)準則有個(gè)前提,那就是帶虛的類(lèi)除外,原因是,memset將類(lèi)清空,有可能將虛表也給置0了。
有可能是因為:類(lèi)的創(chuàng )建分:棧上和堆上。
如果在棧上,那么棧對象的虛函數調用可能會(huì )在靜態(tài)時(shí)確定,從而繞過(guò)虛表。所以不會(huì )出錯。
但堆上就一定會(huì )出錯,下面給出測試代碼:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | class CMemsetVirtualTest // 測試 帶虛類(lèi),被memset為0后,虛表是否失效{public: CMemsetVirtualTest() { memset(this,0,sizeof(CMemsetVirtualTest)); } virtual void NormalFun() { cout<<"test: NormalFun() 虛表指針有效"<<endl; } virtual ~CMemsetVirtualTest() { cout<<"test: ~CMemsetVirtualTest() 虛表指針有效"<<endl; }}; void testFun1() // 測試:棧上建立的對象{ CMemsetVirtualTest Ctest; Ctest.NormalFun();}void testFun2() // 測試:堆上建立的對象{ CMemsetVirtualTest* Ptest = new CMemsetVirtualTest(); Ptest->NormalFun(); // 到這里一定會(huì )暴掉 delete Ptest; // 如果屏蔽上句,到這里也一定會(huì )暴掉} int main(){ CMemsetVirtualTest Ctest;// 測試:棧上建立的對象 Ctest.NormalFun();// 測試正常: CMemsetVirtualTest* Ptest = new CMemsetVirtualTest(); // 測試:堆上建立的對象 Ptest->NormalFun(); // 到這里一定會(huì )暴掉 delete Ptest; // 如果屏蔽上句,到這里也一定會(huì )暴掉} |
即:
在C++中,涉及虛技術(shù)的類(lèi),他的對象內存區塊中就不單純是用戶(hù)定義這個(gè)類(lèi)時(shí)看上去的那些數據結構,編譯器會(huì )在當中安插一些數據或代碼,用來(lái)實(shí)現響應的虛技術(shù).于是當你用memset函數時(shí)會(huì )把這些編譯器安插的東西沖掉, 程序執行結果變得未知. 這時(shí)候如果拷貝對象C++會(huì )使用memberwise拷貝, 此時(shí)編譯器既拷貝用戶(hù)定義的數據結構,還會(huì )對支持虛技術(shù)的相關(guān)設施進(jìn)行適當的修改.
如果對象沒(méi)有用到虛技術(shù), 那么就可以使用memset,就跟正常情況一樣,可以逐位拷貝.
聯(lián)系客服