一般的智能指針都是通過一個普通指針來初始化,所以很容易寫出以下的代碼:
#include <iostream>
using namespace std;
int func1(){
//返回一個整數的函數
}
void func2(AutoPtr<int*> ptr,int t){
//一些操作
}
int main(){
func2(AutoPtr<int*>(new int(5)),func1());
//其他操作
}
乍一看,這段代碼好像沒有什麼問題,但實則暗藏隱患。
我們在調用func2的時候,裡面的參數是需要運算的,運算一共有三步:
我們知道,1一定在2前面調用,但是3的調用順序就不一定了.
我們假設一種情況:調用順序為1->3->2
假設我們在調用3的時候,拋出了一個異常,這時候1已經調用完畢,也就是說,內存已經分配了,但是沒有成功的放入智能指針中。這塊內存不會被自動釋放。於是引發了內存洩漏。
為了避免這個情況,我們可以將該過程分為兩步:
#include <iostream>
using namespace std;
int func1(){
//返回一個整數的函數
}
void func2(AutoPtr<int*> ptr,int t){
//一些操作
}
int main(){
AutoPtr<int*> param(new int(5));
func2(param,func1());
//其他操作
}
只要確保智能指針的初始化不被打斷,該隱患自然就會解除。
即使func1拋出異常,此時,智能指針已經初始化完畢,可以在析構函數中釋放掉管理的內存。