C++基礎知識面試必備、複習細節 (7) (關聯容器、動態內存)
pair類型
-
pair保存兩個數據成員,通常用來存儲具有一定關係的二元組
-
pair<int,string> t; //保存一個int和一個string pair<int,vector<int>> m; //保存一個int和一個vector<int> t=make_pair(i,str); //t的值爲 <i,str> cout<<t.first<<" "<<t.second<<endl; //輸出pair
-
自己常在二維矩陣問題中使用pair<int,int> 用來表示座標
關聯容器
關聯容器類型 | 特點 |
---|---|
map | 關聯數組:關鍵字–值的映射 map<int,string> t : t是一個int到string的映射。 可以通過迭代器進行遍歷,map中元素爲pair類型,first表示鍵,second表示值 實現是紅黑樹實現 |
set | 集合(元素不重複) set<int> t : t是一個保存int的集合,常用find()查找元素是否在set中 可以通過迭代器進行遍歷 實現是紅黑樹實現 |
multimap | 關鍵字可重複的map |
multiset | 關鍵字可重複的set |
unordered_map | 由哈希函數實現的map |
unordered_set | 由哈希函數實現的set |
-
向map中添加元素,可以直接通過 map[key]=val; 實現建立一個key到val的映射關係
-
常用的一個函數 find(k),如果找到則返回第一個關鍵字爲k的元素,否則返回尾之後的迭代器 即end()
-
map內部實現了一個紅黑樹,紅黑樹具有自動排序的功能,因此map內部的所有元素都是有序的;
unordered_map內部實現了一個哈希表,其元素的排列順序是無序的
內存分佈
- 靜態內存:保存局部static對象、類static數據成員以及定義在函數外的變量。在編譯階段自動創建,程序結束才銷燬。
- 棧內存:用來保存定義在函數內的非static對象,自上而下生長。只有在定義的程序塊運行時才存在
- 堆內存:程序員自己動態管理,自下而上生長,用來存儲動態分配的對象。
動態內存
-
在c++中通過new和delete管理動態內存。new,在動態內存中爲對象分配空間並返回一個指向該對象的指針,我們可以選擇對對象初始化; delete接收一個動態對象的指針並銷燬該對象,釋放與之關聯的內存。
-
忘記釋放內存將導致內存泄漏;釋放一個還有別的指針在引用的內存將導致產生非法內存的指針
空懸指針:指針指向的對象空間已經被釋放 野指針:沒用初始化的指針
-
malloc/free 和new/delete的區別
malloc只分配指定大小的堆內存空間,而new可以根據對象類型分配合適的堆內存空間。free釋放對應的堆內存空間,delete,先執行對象的析構函數,在釋放對象所佔空間。malloc分配時的大小是人爲計算的,返回類型是void*,使用時需要類型轉換,new在分配時,編譯器能夠根據對象類型自動計算出大小,返回類型是指向對象類型的指針。new調用構造函數構造對象,而malloc不能;delete將調用析構函數析構對象,而free不能
-
動態數組:
int *pia=new int[size]; //pia指向第一個int for(int* q=pia;q!=pia+size;++q) //遍歷動態數組 /* dosometing() */ delete [] pia;
釋放動態數組時通過 delete [] 釋放
智能指針
-
c++11提供了智能指針來管理動態對象。智能指針可以自動釋放所指向對象
-
shared_ptr類:
#include<memory> share_ptr<string> p1; //shared_ptr,指向string make_shared<T> (args); //返回一個shared_ptr,指向一個動態分配的類型爲T的對象,使用args初始化 auto p1=make_shared<int> (5); //指向一個值爲5的int的shared_ptr shared_ptr<int> p(new int(5));
shared_ptr支持多個指針指向同一區域。當拷貝或賦值時,shared_ptr會動態保存引用計數,當拷貝或賦值時會增加,當修改值或者銷燬時會減少。計數器變爲0時釋放自己所管理的對象。
當shared_ptr銷燬時當調用其析構函數,遞減其引用檢查引用計數是否爲0,如果爲0則將所指向的對象也銷燬,並釋放佔用的內存
注意避免循環引用,shared_ptr的一個最大的陷阱是循環引用(當兩個對象相互使用一個shared_ptr成員變量指向對方,會造成循環引用,使引用計數失效,從而導致內存泄漏)
-
unique_ptr類:
unique_ptr:在某個時刻只能有一個unique_ptr指向一個給定對象,不允許共享。當unique_ptr銷燬時,其指向的對象也被銷燬 unique_ptr不支持拷貝和賦值構造 有效避免資源泄露(例如“以new創建對象後因爲發生異常而忘記調用delete”) 不共享它的指針
unique_ptr<int> p1; unique_ptr<int> p2(new int(42));
-
weak_ptr類:
不增加計數,爲了解決shared_ptr存在相互引用的問題,確保能夠正確析構。是一種不控制對象生命週期的智能指針, 它指向一個 shared_ptr 管理的對象。最大作用在於協助shared_ptr工作,像旁觀者那樣觀測資源的使用情況。weak_ptr可以從一個shared_ptr或者另一個weak_ptr對象構造,獲得資源的觀測權。但weak_ptr沒有共享資源,它的構造不會引起指針引用計數的增加
auto p=make_shared<int>(10); weak_ptr<int> wp(p); //wp弱共享p,p引用計數未改變