首先看一個程序:
創(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)系電話:18980820575int 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)分配的。
在這個程序中,vector
棧上的變量在程序離開它所在的作用域時會自動釋放,因此程序員無需手動釋放。而堆上的變量,需要程序員手動釋放,否則會導(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ū)別:
new會調(diào)用構(gòu)造函數(shù),malloc只會分配內(nèi)存。
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;
}
使用陷阱不要使用裸指針初始化多個智能指針,一個智能指針的use_count為0后會釋放內(nèi)存導(dǎo)致另一個智能指針異常。
與上一個同理不要將一個智能指針的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_ptr
檢查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、expireduse_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)查看詳情吧