1. 程式人生 > >C++智能指針和普通指針轉換需要註意的問題

C++智能指針和普通指針轉換需要註意的問題

情況 問題 ret 臨時 share 沒有 崩潰 ostream 初始

指針是柄雙刃劍,用的好,就會威力倍增;用的稍有閃失,就會造成悲劇。

自從c++11引入智能指針shared_ptr後,我們似乎再也不用擔心new的內存沒有釋放之類的問題了,但是,這樣就萬無一失了嗎?

答案顯然不是的,在智能指針與常規指針轉換的過程中,我們仍需要註意一些坑。

1.常規指針轉換為智能指針:

①.new的普通指針與shared_ptr轉換:

如圖所示,這會發生什麽情況?答案是輸出的會是隨機數,因為經過func函數後,我們用p初始化的臨時智能指針已經被析構了,引用計數先+1,後-1。所以經過func函數後,

p指向的對象被釋放,再解引用自然無法得到我們想要的結果。

#include<iostream>
#include 
<memory> using namespace std; void func(shared_ptr<int>) { ; } int main() { int a = 5; auto p = new int(5); func(shared_ptr<int>(p)); cout << *p << endl; return 0; }

這種情況下,正確的做法如圖所示:一開始就使用智能指針。

#include<iostream>
#include <memory>
using
namespace std; void func(shared_ptr<int>) { ; } int main() { //int a = 5; auto p = make_shared<int>(5); func(shared_ptr<int>(p)); cout << *p << endl; return 0; }

②.指向棧的指針與shared_ptr轉換:

如圖所示,這種情況,程序會直接崩潰,因為智能指針試圖釋放保存在棧上的變量,它越界了。

#include<iostream>
#include 
<memory> using namespace std; void func(shared_ptr<int>) { ; } int main() { int a = 5; auto p = &a; func(shared_ptr<int>(p)); cout << *p << endl; return 0; }

2.智能指針向常規指針的轉換

我們通常使用get()函數向智能指針索要所指向對象的擁有權,但是這樣有時也會造成錯誤:

auto p = make_shared<int>(42);
int* iPtr = p.get();
{
   shared_ptr<int>(iPtr);
}

int value = *p; // Error! 內存已經被釋放

p與iPtr指向了相同的內存,然而通過get方法後,將內存管理權轉移給了普通指針。iPtr傳遞給裏面程序塊的臨時智能指針後,引用計數為1,隨後出了作用域,減少為0,釋放內存。

                                                                                       

C++智能指針和普通指針轉換需要註意的問題