老生常谈,正确使用memset
生活随笔
收集整理的這篇文章主要介紹了
老生常谈,正确使用memset
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前段項目中發現一個問題,程序總是在某個dynamic_cast進行動態轉換時出異常,查了半天才發現問題原來是出在memset的使用上,雖然問題本身顯而易見,但當處于幾十萬行代碼量級中時,就變得不太那么容易定位了。
本文歸納了下使用memset幾個需要注意的地方,雖然內容很簡單,但也希望對大家有所幫助。
1. memset是以字節為單位,初始化內存塊。 當初始化一個字節單位的數組時,可以用memset把每個數組單元初始化成任何你想要的值,比如, [cpp] view plaincopy print?char?data[10];?? memset(data,?1,?sizeof(data));????//?right?? memset(data,?0,?sizeof(data));????//?right??
char data[10];
memset(data, 1, sizeof(data)); // right
memset(data, 0, sizeof(data)); // right
而在初始化其他基礎類型時,則需要注意,比如,
[cpp] view plaincopy print? 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??
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
2. 當結構體類型中包含指針時,在使用memset初始化時需要小心。
比如如下代碼中,
[cpp] view plaincopy print? struct?Parameters?{?? ??????????int?x;?? ??????????int*?p_x;?? };?? Parameters?par;?? par.p_x?=?new?int[10];?? memset(&par,?0,?sizeof(par));?? struct Parameters {int x;int* p_x;
};
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 plaincopy print?class?BaseParameters?? {?? public:?? ????virtual?void?reset()?{}?? };?? ?? class?MyParameters?:?public?BaseParameters?? {?? public:??? ????int?data[3];?? ????int?buf[3];?? };?? ?? MyParameters?my_pars;?? memset(&my_pars,?0,?sizeof(my_pars));?? BaseParameters*?pars?=?&my_pars;?? ?? //......?? ?? MyParameters*?my?=?dynamic_cast<MyParameters*>(pars);?? class BaseParameters
{
public:virtual void reset() {}
};class MyParameters : public BaseParameters
{
public: int data[3];int buf[3];
};MyParameters my_pars;
memset(&my_pars, 0, sizeof(my_pars));
BaseParameters* pars = &my_pars;//......MyParameters* my = dynamic_cast<MyParameters*>(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的鏈接已經被破壞,導致程序發生異常。
1. memset是以字節為單位,初始化內存塊。 當初始化一個字節單位的數組時,可以用memset把每個數組單元初始化成任何你想要的值,比如, [cpp] view plaincopy print?
3. 當結構體或類的本身或其基類中存在虛函數時,也需要謹慎使用memset。 這個問題就是在開頭項目中發現的問題,如下代碼中, [cpp] view plaincopy print?
總結
以上是生活随笔為你收集整理的老生常谈,正确使用memset的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: matlab多元函数_函数的计算机处理8
- 下一篇: c的关于数组初始化 和 memset用法