真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++入門(2)內(nèi)存泄露與智能指針-創(chuàng)新互聯(lián)

一、內(nèi)存泄漏是什么

首先看一個程序:

創(chuàng)新互聯(lián)2013年開創(chuàng)至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目網(wǎng)站設(shè)計、做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元安陽做網(wǎng)站,已為上家服務(wù),為安陽各地企業(yè)和個人服務(wù),聯(lián)系電話:18980820575
int main() {
    int a = 1;
    int b = 2;
    vectorv2{&a, &b};
    while (!v2.empty()) {
        auto iter = v2.begin();
        delete *iter;
        v2.erase(iter);
    }
}

這個程序會報錯:free(): invalid pointer

原因:這個程序中的問題在于,它是在使用delete刪除堆上的變量,而在這里a和b是棧上的變量,不能用delete刪除。所以這個程序會導(dǎo)致野指針錯誤。

進一步解釋:堆和棧是兩種不同的存儲空間,在 C++ 中用來存儲不同類型的變量。

  • 棧上的變量是由編譯器自動分配和釋放的,速度快,但是空間大小有限,不能動態(tài)增長。棧上的變量通常是局部變量或者是函數(shù)參數(shù)。

  • 堆上的變量是由程序員手動分配和釋放的,速度慢,但是空間大小可以動態(tài)增長。堆上的變量通常是使用 new 關(guān)鍵字動態(tài)分配的。

在這個程序中,vectorv2{&a, &b};這行代碼創(chuàng)建了一個 vector 對象,并將棧上的變量 a 和 b 的地址存儲在了 vector 中。而在 while 循環(huán)中,使用了 delete *iter;這行代碼將這些地址對應(yīng)的內(nèi)存釋放,但是在棧上的變量 a 和 b 沒有被釋放,會導(dǎo)致程序崩潰。

棧上的變量在程序離開它所在的作用域時會自動釋放,因此程序員無需手動釋放。而堆上的變量,需要程序員手動釋放,否則會導(dǎo)致內(nèi)存泄漏。

正確程序:

int main() {
    vectorv2;
    v2.push_back(new int(1));
    v2.push_back(new int(2));
    while (!v2.empty()) {
        auto iter = v2.begin();
        delete *iter;
        v2.erase(iter);
    }
}
二、內(nèi)存閱讀方法

為方便調(diào)試和觀察,可以使用memory view。格式說明:

每個“兩位數(shù)”表示一個字節(jié)空間所對應(yīng)的值,一個字節(jié)是8位的,用兩個16進制數(shù)剛好表示出來(每個數(shù)4位)。在gpd中輸入 p &變量名 即可獲得變量所對應(yīng)的內(nèi)存地址。

三、智能指針之shared_ptr 基本用法

new delete和malloc free的區(qū)別:

  1. new會調(diào)用構(gòu)造函數(shù),malloc只會分配內(nèi)存。

  1. delete會調(diào)用對象的析構(gòu)函數(shù),而free不會調(diào)用任何函數(shù)。

智能指針(shared_ptr)

  • make_shared高效安全,從堆(動態(tài)內(nèi)存)中初始化一個對象。相當(dāng)于new。

  • p.reset() 相當(dāng)于delete。

可以多個指針指向同一個內(nèi)存,內(nèi)部有一個計數(shù)變量,會記錄被多少指針指向。程序員無需手動釋放他,系統(tǒng)會自動釋放。

此時:

如果我們此時調(diào)用ps1.reset()

再舉一個例子:

#include "iostream"
#includeusing namespace std;
int main() {
    shared_ptrp = make_shared(1);
    cout<< p.use_count()<< endl;//1
    p.reset();
    cout<< p.use_count()<< endl;//0
    cout<< (p == nullptr)<< endl;//true
    return 0;
}
使用陷阱
  1. 不要使用裸指針初始化多個智能指針,一個智能指針的use_count為0后會釋放內(nèi)存導(dǎo)致另一個智能指針異常。

  1. 與上一個同理不要將一個智能指針的get()綁定到另一個智能指針上,例如一下程序無法正常運行。

int main() {
    shared_ptrp = make_shared(10);
    int *p_bare = p.get();
    {
        shared_ptrp2(p_bare);
    }
    cout<< p.use_count()<< endl;
}

解決方法:只有智能指針或make_shared初始化智能指針。只有比較古老的需要裸指針的API采用get(內(nèi)部不會釋放指針也不會用它初始化智能指針)。

四、智能指針之weak_ptr

輔助shared_ptr工作(像一個旁觀者),weak是弱,強指的是shared_ptr。weak_ptr也是一個類模板,用來指向shared_ptr管理的對象但是weak_ptr這種指向不會控制所指向?qū)ο蟮纳芷凇<床粫淖僺hared_ptr的引用計數(shù)??梢杂糜诮鉀Q循環(huán)引用的問題。

weak_ptr的創(chuàng)建

用shared_ptr來初始化。weak_ptrpw(ps)

常用操作 lock

檢查weak_ptr是否存在,如果存在則返回指向?qū)ο蟮膕hared_ptr否則返回一個空的shared_ptr。

intmain(){
    autosp=make_shared(100);
    // wc = 0, uc = 1
    autowp=weak_ptr(sp);
    // wc = 1, uc = 1
    autosp2=wp.lock();
    // wc = 1, uc = 2
    return0;
}
use_count、reset、expired

use_count返回強引用個數(shù),reset釋放,expired判斷use_count是否為0。

weak_count

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁題目:C++入門(2)內(nèi)存泄露與智能指針-創(chuàng)新互聯(lián)
路徑分享:http://weahome.cn/article/hegco.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部