**:老生常談,正確使用memset
本文歸納了下使用memset幾個需要注意的地方,雖然內容很簡單,但也希望對大家有所幫助。
1. memset是以位元組為單位,初始化記憶體塊。
當初始化乙個位元組單位的陣列時,可以用memset把每個陣列單元初始化成任何你想要的值,比如:
而在初始化其他基礎型別時,則需要注意,比如:char data[10];
memset(data, 1, sizeof(data)); // right
memset(data, 0, sizeof(data)); // right
比如:int data[10];
memset(data, 0, sizeof(data)); // right
memset(data, -1, sizeof(data)); // right
memset(data, 1, sizeof(data)); // wrong, data[x] would be 0x0101 instead of 1
float (*p)[40]=new float[100][40];
memset(p,1,100*40);
因為memset是以位元組為單位進行賦值,每個都用ascii為1的字元去填充,轉為二進位制後,1就是00000001,佔乙個位元組。乙個float元素是4位元組,合一起就是00000001000000010000000100000001,轉換成十進位制明顯不是我們想要的結果。而3是沒有把所有的記憶體全部清空。
所以用memset對非字元型陣列賦初值是不可取的!清空記憶體卻可以做到。
2. 當結構體型別中包含指標時,在使用memset初始化時需要小心。
比如如下**:
當memset初始化時,並不會初始化p_x指向的int陣列單元的值,而會把已經分配過記憶體的p_x指標本身設定為0,造成記憶體洩漏。同理,對std::vector等資料型別,顯而易見也是不應該使用memset來初始化的。struct parameters ;
parameters par;
par.p_x = new int[10];
memset(&par, 0, sizeof(par));
3. 當結構體或類的本身或其基類中存在虛函式時,也需要謹慎使用memset。
這個問題就是在開頭專案中發現的問題,如下**中,
程式執行到dynamic_cast時發生異常。原因其實也很容易發現,我們的目的是為了初始化資料結構myparameters裡的data和buf,正常來說需要初始化的記憶體空間是sizeof(int) * 3 * 2 = 24位元組,但是使用memset直接初始化myparameters型別的資料結構時,sizeof(my_pars)卻是28位元組,因為為了實現多型機制,c++對有虛函式的物件會包含乙個指向虛函式表(v-table)的指標,當使用memset時,會把該虛函式表的指標也初始化為0,而dynamic_cast也使用rtti技術,執行時會使用到v-table,可此時由於與v-table的鏈結已經被破壞,導致程式發生異常。class baseparameters
};
class myparameters : public baseparameters
; myparameters my_pars;
memset(&my_pars, 0, sizeof(my_pars));
baseparameters* pars = &my_pars;
//......
myparameters* my = dynamic_cast(pars);
c語言之memset函式詳解
功 能 將s所指向的某一塊記憶體中的每個位元組的內容全部設定為ch指定的ascii值,塊的大小由第三個引數指定,這個函式通常為新申請的記憶體做初始化工作 用 法 void memset void s,char ch,unsigned n 程式例 include include include int...
c語言memset()函式
1 名稱 memset 函式 2 別稱 char型初始化函式 3 功能 將s所指向的某一塊記憶體中的每個位元組的內容全部設定為ch指定的ascii值,塊的大小由第三個引數指定,這個函式通常為新申請的記憶體做初始化工作 4 用法 void memset void s,char ch,unsigned ...
C語言的memset 函式
c語言memset 函式 將記憶體的前n個位元組設定為特定的值 標頭檔案 include memset 函式用來將指定記憶體的前n個位元組設定為特定的值,其原型為 void memset void ptr,intvalue,size tnum 引數說明 ptr 為要操作的記憶體的指標。value 為...