標籤:動態二維素組 c++ stl vector 記憶體
之前在這裡寫過一篇“C++中的動態二維數組”。在C++中沒有動態二維(多維)數組。但是根據原理我們可以自己建立。
在看過STL的vector原始碼後"《STL源碼剖析》---stl_vector.h閱讀筆記"後,想到可以用容器的容器來做二維數組。
建立一個2x4的二維數組。想到的辦法是:先建立一個容器的容器,外層大小的2(2行),然后里面容器小大為4(4列)。
int row=2,col=4;vector<vector<int> > v(row);//v為容器的容器,大小為2.for(int i=0; i<row; i++)v[i].resize(col);//裡層容器大小設定為4
那麼v是怎麼使用記憶體的呢?
我知道vector開闢的是連續記憶體,但是vector內部的元素也是vector,內部的vector大小不知道且可變,並且內部的vector們大小也可能不一樣。但是vector要求元素所佔用空間是相同的,因此內部的vector中儲存的元素一定不佔用外部vector v的空間。
在分析了vector原始碼後,可以知道vector只有三個成員變數:
iterator start; iterator finish; iterator end_of_storage;
這三個都是原生態指標,在32位機上佔用12位元組。因此每個內部元素vector只佔用12個位元組,內部元素vector儲存的元素在其他地方開闢記憶體。寫代碼驗證一下:
vector<vector<int> >::iterator iter1=v.begin();vector<vector<int> >::iterator iter2=iter1+1;cout<<"兩個迭代器之間的距離(差值)"<<(int)iter2-(int)iter1<<endl;cout<<"vector佔用記憶體大小:"<<sizeof(vector<int>)<<endl;
輸出為:
兩個迭代器之間的距離(差值)12
vector佔用記憶體大小:12
驗證了上面的說法。內部元素vector在其他地方開闢記憶體是連續的,也就是說每一行的元素佔用記憶體是連續的。再寫代碼驗證一下:
for(int i=0; i<row; i++)//初始化元素的值for(int j=0; j<col; j++)v[i][j]=i*col+j+1;for(int i=0; i<row; i++)//輸出其地址和值{<span style="white-space:pre"></span>for(int j=0; j<col; j++)<span style="white-space:pre"></span>cout<<&v[i][j]<<":"<<v[i][j]<<" ";cout<<endl;}輸出為:
0x0012bb60:1 0x0012bb64:2 0x0012bb68:3 0x0012bb6c:4
0x0012bc90:5 0x0012bc94:6 0x0012bc98:7 0x0012bc9c:8
可見行的記憶體是連續的。
因此得出結論:
vector<vector<int> > v構建的動態二維數組,內部vector只佔用12位元組(32位機器)。從其原始碼可以看到,其實所有vector只需3個成員變數。vector中的元素儲存在動態開闢的記憶體上。
下面貼上測試代碼,用的vector是SGI版本的STL,用其他版本的vector佔用記憶體可能不一樣,我用vs2010內建的試了一下,佔用20個位元組。
#include<iostream>#include<fstream>#include"vector"using namespace std;int main(){ofstream fout("result.txt");int row=2,col=4;vector<vector<int> > v(row);//v為容器的容器,大小為2.for(int i=0; i<row; i++)v[i].resize(col);//裡層容器大小設定為4vector<vector<int> >::iterator iter1=v.begin();vector<vector<int> >::iterator iter2=iter1+1;fout<<"兩個迭代器之間的距離(差值)"<<(int)iter2-(int)iter1<<endl;fout<<"vector佔用記憶體大小:"<<sizeof(vector<int>)<<endl;for(int i=0; i<row; i++)//初始化元素的值for(int j=0; j<col; j++)v[i][j]=i*col+j+1;for(int i=0; i<row; i++)//輸出其地址和值{for(int j=0; j<col; j++)fout<<&v[i][j]<<":"<<v[i][j]<<" ";fout<<endl;}return 0;}
上面的fout只是把結果輸出到檔案result.txt中了,便於複製。