頭文件:
#include <string.h>
memset() 函數用來將指定內存的前n個字節設置為特定的值,其原型為:
void * memset( void * ptr, int value, size_t num );
參數說明:
ptr 為要操作的內存的指針。
value 為要設置的值。你既可以向 value 傳遞 int 類型的值,也可以傳遞 char 類型的值,int 和 char 可以根據 ASCII 碼相互轉換。
num 為 ptr 的前 num 個字節,size_t 就是unsigned int。
【函數說明】memset() 會將 ptr 所指的內存區域的前 num 個字節的值都設置為 value,然后返回指向 ptr 的指針。
memset() 可以將一段內存空間全部設置為特定的值,所以經常用來初始化字符數組。例如:
char str[20];memset(str, '/0', sizeof(str)-1);
【返回值】返回指向 ptr 的指針。
注意:參數 value 雖聲明為 int,但必須是 unsigned char,所以范圍在0 到255 之間。
范例:
#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){ // 不可以聲明為 char *str = "http://c.biancheng.net"; char str[] = "http://c.biancheng.net"; memset(str, '-', 7); puts(str); system("pause"); return EXIT_SUCCESS;}
執行結果:
-------c.biancheng.net
優化:盡量用memset將一個數組設置清零(帶虛類除外),而不是通過for循環逐個置0
下面這個例子,大家可以參考:3D游戲編程大師技巧。本文其實重點是memset,原因是在工作中,用的比較多。
例如:要清空一個float f[10000],應該用memset(f,0,sizeof(float) * 10000);
而不是: for(int i=0; i<10000; ++i) f[i] = 0;
當然,還可以用內嵌匯編的形式:
_asm { mov edi, f; // edi指向數組地的目標內存的起始處 mov ecx, 1000/4; // 循環次數或移動次數 mov eax, 0; // 每一次移動32位數,都置0 rep stosd; // 移動數據 }
哈,這個準則有個前提,那就是帶虛的類除外,原因是,memset將類清空,有可能將虛表也給置0了。
有可能是因為:類的創建分:棧上和堆上。
如果在棧上,那么棧對象的虛函數調用可能會在靜態時確定,從而繞過虛表。所以不會出錯。
但堆上就一定會出錯,下面給出測試代碼:
class CMemsetVirtualTest // 測試 帶虛類,被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(); // 到這里一定會暴掉 delete Ptest; // 如果屏蔽上句,到這里也一定會暴掉} int main(){ CMemsetVirtualTest Ctest;// 測試:棧上建立的對象 Ctest.NormalFun();// 測試正常: CMemsetVirtualTest* Ptest = new CMemsetVirtualTest(); // 測試:堆上建立的對象 Ptest->NormalFun(); // 到這里一定會暴掉 delete Ptest; // 如果屏蔽上句,到這里也一定會暴掉}
即:
在C++中,涉及虛技術的類,他的對象內存區塊中就不單純是用戶定義這個類時看上去的那些數據結構,編譯器會在當中安插一些數據或代碼,用來實現響應的虛技術.于是當你用memset函數時會把這些編譯器安插的東西沖掉, 程序執行結果變得未知. 這時候如果拷貝對象C++會使用memberwise拷貝, 此時編譯器既拷貝用戶定義的數據結構,還會對支持虛技術的相關設施進行適當的修改.
如果對象沒有用到虛技術, 那么就可以使用memset,就跟正常情況一樣,可以逐位拷貝.
新聞熱點
疑難解答
圖片精選