1. 程式人生 > >C++ 釋放指向類的void型別指標造成記憶體洩漏

C++ 釋放指向類的void型別指標造成記憶體洩漏

先來看一段程式碼

#include <iostream>
using namespace std;

class A
{
public:
	A(){
		cout << "A() ...." << endl;
	}
	~A()
	{
		cout << "~A()...." << endl;
	}
	void func()
	{
		cout << "a --> func()...." << endl;
	}
};


class MyAutoPtr //定義一個指向A類的智慧指標
{
public:
	MyAutoPtr(void* ptr) //ptr = new A;
	{
		this->m_p = ptr;
	}

	~MyAutoPtr()
	{
		if (this->m_p != NULL) {
			cout << "delete m_p" << endl;//列印資訊,表示已執行MyAutoPtr類的解構函式
			delete m_p;
		}
	}
private:
	void* m_p;//指向A物件的地址。
};



void test()
{
	MyAutoPtr auto_p(new A); //建立一個物件,並在test函式結束時銷燬

}



int main(void)
{
	test();

	return 0;
}

輸出結果如下

A() ....
delete m_p

這段程式碼中MyAutoPtr類中有一個void類指標m_p指向類A,最後在物件auto_p銷燬時呼叫MyAutoPtr類中解構函式釋放掉m_p指向的記憶體即類A,按理來說是會呼叫類A的解構函式進行進一步的釋放,但是輸出結果表示系統只執行到了MyAutoPtr類中的解構函式,並未呼叫類A的解構函式,這就造成了類A的記憶體並未被釋放。

若將MyAutoPtr類中的指標m_p改為A型別,再次執行就顯示正確的呼叫了類A的解構函式。

由此可知,若一個void型別指標指向了一個類,那麼系統在釋放這個指標時並不會呼叫該類中的解構函式去釋放記憶體,會造成記憶體洩漏。這也是為什麼C++中模板類大多需要呼叫者在呼叫時顯式標註資料型別的原因。