close
C++ void *的陷阱-解構失敗
考慮以下的程式
//test.h
class A
{
public:
A(){cout<<"A constructor."<<endl;}
~A(){cout<<"A destructor."<<endl;}
};
class B
{
public:
void *m_pObj;
public:
B()
{
m_pObj = 0;
cout<<"B constructor."<<endl;
}
~B()
{
if(m_pObj)
{
delete m_pObj;
m_pObj = 0;
}
cout<<"B destructor."<<endl;
}
};
//main.cpp
int main()
{
B *pB = new B();
pB->m_pObj = (void*)(new A());
delete pB;
system("pause");
return 0;
}
執行結果
B constructor. |
咦?A destructor.不見了?
明明就有 B destructor. ,可是卻沒有 delete A ?
主要原因就在於,A 在 B 裡的型別是 void ,而不是 class A,所以在解構時就不會執行到 class A 的 destructor。一旦 B 的數量變多時,裡面的 A 又沒有辦法解構,記憶體很快就會被吃光了,造成非常嚴重的 memory leak。
會出現這種程式碼其實是因為要存放不同型別的資料,或許有人會說就用多型就好了啊,但問題是當一個專案經過了五六年後,根本動不了那個繼承架構,所以才會出現這種折衷方案。
解決方法就是,既然一開始就是在外部 new A 再轉型成 void,那就只好拿出來再轉回 A,再去 delete。
int main()
{
B *pB = new B();
pB->m_pObj = (void*)(new A());
delete (A *)pB->m_pObj;
pB->m_pObj = 0;
delete pB;
system("pause");
return 0;
}
執行結果
B constructor. |
文章標籤
全站熱搜
留言列表