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


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

自從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,釋放內存。

                                                                                       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM