c++ vector造成的內(nèi)存泄漏問(wèn)題
c++ vector造成的內(nèi)存泄漏
C++中的
std::liststd::arraystd::queuestd::mapstd::setstd::vectorstd::forward_liststd::multisetstd::multimapstd::stackstd::unorderd_mapstd::unorderd_multimapstd::unorderd_setstd::unorderd_multiset
在任何成員方法中均不管理程序員動(dòng)態(tài)分配的內(nèi)存。
先附上解決方法
vector<Data*> g_vec;
void release()
{
// 程序員自己管理 自己動(dòng)態(tài)分配的內(nèi)存
for_each(g_vec.begin(), g_vec.end(), [](Data*& iter) {delete iter; iter = nullptr; });
}測(cè)試數(shù)據(jù):
struct Data
{
explicit Data(const int val) noexcept :m_var(val)
{
cout<<"構(gòu)造函數(shù):"<<this->m_var<<endl;
}
Data(const Data& other) noexcept
{
cout<<"copy構(gòu)造函數(shù):"<<other.m_var<<endl;
this->m_var = other.m_var;
}
Data(Data&& other) noexcept
{
cout<<"move構(gòu)造函數(shù):"<<other.m_var<<endl;
this->m_var = other.m_var;
other.m_var = 0;
}
Data& operator=(const Data& other) noexcept
{
if(this == &other)
{
return *this;
}
cout<<"賦值運(yùn)算符函數(shù):"<<other.m_var<<endl;
this->m_var = other.m_var
return *this;
}
Data& operator=(Data&& other) noexcept
{
if (this == &other)
{
return *this;
}
cout<<"move賦值運(yùn)算符函數(shù):"<<other.m_var<<endl;
this->m_var = other.m_var;
other.m_var = 0;
return *this;
}
~Data()
{
cout<<"析構(gòu)函數(shù):"<<this->m_var<<endl;
}
private:
int m_var;
};幾個(gè)重點(diǎn)
- vector<Data*>在vector的任何方法中和中間過(guò)程都不調(diào)用Data的成員函數(shù)。
- Data的copy構(gòu)造的參數(shù)必須是const,否則報(bào)錯(cuò): <沒(méi)有可用的復(fù)制構(gòu)造函數(shù)或復(fù)制構(gòu)造函數(shù)聲明為"explicit">
- move構(gòu)造和move賦值運(yùn)算符必須是noexcept,否則調(diào)用copy構(gòu)造和普通賦值運(yùn)算符
內(nèi)存分配策略
vector<Data*> dataVec;
for (int i=0;i<10;++i)
{
dataVec.push_back(new Data(i + 1));
cout << "\tmem size:" << dataVec.capacity() << ", vec size:" << dataVec.size() << endl;
}vector.capacity()返回vector當(dāng)前分配的內(nèi)存總量。vector.size()返回vector當(dāng)前有多少元素。

vector.push_back的過(guò)程是先判斷
if (size()==capacity()) capacity=1.5*capacity;
并不是在原來(lái)的基礎(chǔ)上擴(kuò)大2倍。
修改capacity的三種方法
vector.reserve(size_type new_len)如果new_len<=capacity()什么都不做;如果new_len>capacity(),重新分配內(nèi)存,最后的capacity()可能>=new_lenvector.shrink_to_fit()重新分配內(nèi)存使capacity()==size(),意思就是把原來(lái)沒(méi)有用到的內(nèi)存釋放掉。vector.swap或者std::swap,交換的過(guò)程中包含capacity的改變。
capacity誤區(qū)
- operator=, vector.assign, vector.erase, vector.clear不會(huì)修改capacity
內(nèi)存釋放誤區(qū)
- vector.clear, vector.earse不會(huì)釋放程序員自己動(dòng)態(tài)分配的內(nèi)存
vector——防止內(nèi)存溢出的處理
利用swap() 交換函數(shù),可進(jìn)行內(nèi)存的防止溢出。
如下所示:
vector p1; p1.resize(10000); p1.push_back(1); p1.push_back(2); p1.push_back(3); //當(dāng)使用內(nèi)存空間遠(yuǎn)遠(yuǎn)小于開(kāi)辟的空間時(shí),造成內(nèi)存浪費(fèi)和內(nèi)存溢出的危險(xiǎn)。 //利用匿名對(duì)象的特性:匿名對(duì)象使用結(jié)束后,內(nèi)存自動(dòng)回收。 vector(p1).swap(p1);
可以有效的將內(nèi)存空間進(jìn)行回收。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言用封裝方法實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言用封裝方法實(shí)現(xiàn)飛機(jī)大戰(zhàn)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
C++實(shí)現(xiàn)二叉樹(shù)的堂兄弟節(jié)點(diǎn)查詢
C++實(shí)現(xiàn)二叉樹(shù)的堂兄弟節(jié)點(diǎn)查詢,是指在二叉樹(shù)中,找到兩個(gè)節(jié)點(diǎn)深度相同但父節(jié)點(diǎn)不同的節(jié)點(diǎn),即為堂兄弟節(jié)點(diǎn)。實(shí)現(xiàn)這一功能可以通過(guò)遍歷二叉樹(shù)并記錄節(jié)點(diǎn)深度和父節(jié)點(diǎn)來(lái)實(shí)現(xiàn)2023-04-04
Qt使用QCustomPlot的實(shí)現(xiàn)示例
QCustomPlot是一個(gè)基于Qt C++的圖形庫(kù),用于繪制和數(shù)據(jù)可視化,并為實(shí)時(shí)可視化應(yīng)用程序提供高性能服務(wù),本文主要介紹了Qt使用QCustomPlot的實(shí)現(xiàn)示例,感興趣的可以了解一下2024-01-01
C++使用數(shù)組來(lái)實(shí)現(xiàn)哈夫曼樹(shù)
給定N個(gè)權(quán)值作為N個(gè)葉子結(jié)點(diǎn),構(gòu)造一棵二叉樹(shù),若該樹(shù)的帶權(quán)路徑長(zhǎng)度達(dá)到最小,稱這樣的二叉樹(shù)為最優(yōu)二叉樹(shù),也稱為哈夫曼樹(shù)(Huffman?Tree)。哈夫曼樹(shù)是帶權(quán)路徑長(zhǎng)度最短的樹(shù),權(quán)值較大的結(jié)點(diǎn)離根較近2022-05-05
DEV C++自動(dòng)補(bǔ)全文件頭的設(shè)置操作教程
Dev-C++ 是一款輕量級(jí)的集成開(kāi)發(fā)環(huán)境 (IDE),主要用于 C 和 C++ 的程序編寫,它提供了基本的功能來(lái)幫助開(kāi)發(fā)者更高效地工作,其中包括文件頭的自動(dòng)補(bǔ)全功能,本文就給大家介紹了DEV C++自動(dòng)補(bǔ)全文件頭的設(shè)置操作教程,需要的朋友可以參考下2025-04-04
C++動(dòng)態(tài)內(nèi)存分配(new/new[]和delete/delete[])詳解
這篇文章主要介紹了C++動(dòng)態(tài)內(nèi)存分配(new/new[]和delete/delete[])詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05

