首先看一個(gè)程序:
創(chuàng)新互聯(lián)2013年開(kāi)創(chuàng)至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站設(shè)計(jì)、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元安陽(yáng)做網(wǎng)站,已為上家服務(wù),為安陽(yáng)各地企業(yè)和個(gè)人服務(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);
}
}
這個(gè)程序會(huì)報(bào)錯(cuò):free(): invalid pointer
原因:這個(gè)程序中的問(wèn)題在于,它是在使用delete刪除堆上的變量,而在這里a和b是棧上的變量,不能用delete刪除。所以這個(gè)程序會(huì)導(dǎo)致野指針錯(cuò)誤。
進(jìn)一步解釋:堆和棧是兩種不同的存儲(chǔ)空間,在 C++ 中用來(lái)存儲(chǔ)不同類(lèi)型的變量。
棧上的變量是由編譯器自動(dòng)分配和釋放的,速度快,但是空間大小有限,不能動(dòng)態(tài)增長(zhǎng)。棧上的變量通常是局部變量或者是函數(shù)參數(shù)。
堆上的變量是由程序員手動(dòng)分配和釋放的,速度慢,但是空間大小可以動(dòng)態(tài)增長(zhǎng)。堆上的變量通常是使用 new 關(guān)鍵字動(dòng)態(tài)分配的。
在這個(gè)程序中,vector
棧上的變量在程序離開(kāi)它所在的作用域時(shí)會(huì)自動(dòng)釋放,因此程序員無(wú)需手動(dòng)釋放。而堆上的變量,需要程序員手動(dòng)釋放,否則會(huì)導(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。格式說(shuō)明:
每個(gè)“兩位數(shù)”表示一個(gè)字節(jié)空間所對(duì)應(yīng)的值,一個(gè)字節(jié)是8位的,用兩個(gè)16進(jìn)制數(shù)剛好表示出來(lái)(每個(gè)數(shù)4位)。在gpd中輸入 p &變量名 即可獲得變量所對(duì)應(yīng)的內(nèi)存地址。
三、智能指針之shared_ptr 基本用法new delete和malloc free的區(qū)別:
new會(huì)調(diào)用構(gòu)造函數(shù),malloc只會(huì)分配內(nèi)存。
delete會(huì)調(diào)用對(duì)象的析構(gòu)函數(shù),而free不會(huì)調(diào)用任何函數(shù)。
智能指針(shared_ptr)
make_shared高效安全,從堆(動(dòng)態(tài)內(nèi)存)中初始化一個(gè)對(duì)象。相當(dāng)于new。
p.reset() 相當(dāng)于delete。
可以多個(gè)指針指向同一個(gè)內(nèi)存,內(nèi)部有一個(gè)計(jì)數(shù)變量,會(huì)記錄被多少指針指向。程序員無(wú)需手動(dòng)釋放他,系統(tǒng)會(huì)自動(dòng)釋放。
此時(shí):
如果我們此時(shí)調(diào)用ps1.reset()
再舉一個(gè)例子:
#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;
}
使用陷阱不要使用裸指針初始化多個(gè)智能指針,一個(gè)智能指針的use_count為0后會(huì)釋放內(nèi)存導(dǎo)致另一個(gè)智能指針異常。
與上一個(gè)同理不要將一個(gè)智能指針的get()綁定到另一個(gè)智能指針上,例如一下程序無(wú)法正常運(yùn)行。
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)部不會(huì)釋放指針也不會(huì)用它初始化智能指針)。
四、智能指針之weak_ptr輔助shared_ptr工作(像一個(gè)旁觀者),weak是弱,強(qiáng)指的是shared_ptr。weak_ptr也是一個(gè)類(lèi)模板,用來(lái)指向shared_ptr管理的對(duì)象但是weak_ptr這種指向不會(huì)控制所指向?qū)ο蟮纳芷凇<床粫?huì)改變shared_ptr的引用計(jì)數(shù)??梢杂糜诮鉀Q循環(huán)引用的問(wèn)題。
weak_ptr的創(chuàng)建用shared_ptr來(lái)初始化。weak_ptr
檢查weak_ptr是否存在,如果存在則返回指向?qū)ο蟮膕hared_ptr否則返回一個(gè)空的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返回強(qiáng)引用個(gè)數(shù),reset釋放,expired判斷use_count是否為0。
weak_count
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
本文標(biāo)題:C++入門(mén)(2)內(nèi)存泄露與智能指針-創(chuàng)新互聯(lián)
轉(zhuǎn)載來(lái)源:http://muchs.cn/article20/hegco.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、手機(jī)網(wǎng)站建設(shè)、響應(yīng)式網(wǎng)站、微信公眾號(hào)、定制網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容