今天遇到乙個很詭異的記憶體洩露,記錄如下:
1.兩個類,記為a,b。其中a有應指向b的指標;b也有指標成員,指向new出來的空間。兩個類定義如下:
1.1檔案a.h
class b;
class a;
1.2 檔案a.cpp
#include "a.h"
a::~a()
}1.3 檔案b.hclass b;
1.4 檔案b.cpp
#include "b.h"
b::b()
b::~b()
}
根據上述定義,可以看出:
1)b類裡有new的指標,因此需要自定義析構函式,否則會造成記憶體洩露;
2)a類中有b的指標(下面會用new來賦值),但a.h檔案只是宣告了b類,而不是包含b類的標頭檔案。a.cpp檔案也未包含b.h,因此也是看不到b類的定義的。
2.下面給出main函式:
#include "a.h"
#include "b.h"
int main()
上述**會造成記憶體洩露!
3.分析:
理論上說,執行delete pa;會呼叫a的析構函式,而a的析構函式又會呼叫b的析構函式,b的析構函式析構new出來的陣列空間。然而實際上並非如此,上述**會造成記憶體洩露。原因如下:
執行delete pa;會呼叫a類的析構函式,這步沒有錯。a類的析構函式會執行delete m_pb;這步並不會呼叫b類的析構函式,原因在於a類的析構函式看不到b類的定義,所以也就不知道b類定義了自己的析構函式,它只釋放了b類占用的空間(不包括b類裡m_p0指標指向的空間)。因此造成記憶體洩露。
解決方法很簡單:在a.cpp中包含標頭檔案b.h。
4.總結:
這個**是在vs2010裡寫的,我不確定上述問題是c++語法的問題,還是vs的問題。有上面的分析我搞明白了delete所做的工作,delete乙個指標p,p指向的物件的大小size肯定是知道的,那麼delete的功能就是釋放從p開始,大小為size的連線空間。
類String的建構函式 析構函式和賦值函式
海康威視16年春季校招程式設計題目 題目 編寫類string的建構函式 析構函式和賦值函式,已知類string的原型為 class string 解答 1 普通建構函式 建構函式 建構函式是一種特殊的方法,主要用來在建立物件時初始化物件,即為物件成員變數賦初始值,總與new運算子一起使用在建立物件的...
包含物件成員的類的構造與析構順序
includeusing namespace std class a a class b b class c c a ainc class d public c d a aind private b bind int main void 那麼,這段程式執行後,輸出什麼呢?b s constructo...
Qt裡頭檔案包含的類的宣告
1 qt begin namespace 例如 ifndef mainwindow h define mainwindow h include qt begin namespaceclass qaction class qmenu class qtextedit qt end namespace在標...