**:
前段專案中發現乙個問題,程式總是在某個dynamic_cast進行動態轉換時出異常,查了半天才發現問題原來是出在memset的使用上,雖然問題本身顯而易見,但當處於幾十萬行**量級中時,就變得不太那麼容易定位了。
本文歸納了下使用memset幾個需要注意的地方,雖然內容很簡單,但也希望對大家有所幫助。
1. memset是以位元組為單位,初始化記憶體塊。
當初始化乙個位元組單位的陣列時,可以用memset把每個陣列單元初始化成任何你想要的值,比如,
[cpp]
view plain
copy
char
data[10];
memset(data, 1, sizeof
(data));
// right
memset(data, 0, sizeof
(data));
// right
而在初始化其他基礎型別時,則需要注意,比如,
[cpp]
view plain
copy
intdata[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
2. 當結構體型別中包含指標時,在使用memset初始化時需要小心。
比如如下**中,
[cpp]
view plain
copy
struct
parameters ;
parameters par;
par.p_x = new
int[10];
memset(&par, 0, sizeof
(par));
當memset初始化時,並不會初始化p_x指向的int陣列單元的值,而會把已經分配過記憶體的p_x指標本身設定為0,造成記憶體洩漏。同理,對std::vector等資料型別,顯而易見也是不應該使用memset來初始化的。
3. 當結構體或類的本身或其基類中存在虛函式時,也需要謹慎使用memset。
這個問題就是在開頭專案中發現的問題,如下**中,
[cpp]
view plain
copy
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);
程式執行到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的鏈結已經被破壞,導致程式發生異常。memset,記憶體初始化函式
include void memset void s,int c,unsigned long n 函式的功能是 將指標變數 s 所指向的前 n 位元組的記憶體單元用乙個 整數 c 替換,注意 c 是 int 型。s 是 void 型的指標變數,所以它可以為任何型別的資料進行初始化。memset 的作...
memset函式 記憶體初始化介紹
memset函式詳細說明 收藏 1。void memset void s,int c,size t n 總的作用 將已開闢記憶體空間 s 的首 n 個位元組的值設為值 c。2。例子 include void main 3。memset 函式常用於記憶體空間初始化。如 char str 100 mem...
memset函式初始化
對於絕大多數編譯器來講,char namekey 15 與memset namekey,0x0,sizeof namekey 或memset namekey,0 sizeof namekey 這三個是一樣的。但是有的編譯器,char namekey 15 只將namekey 0 給賦值為 0 其他成...