Re: [問題] variable bytes size limit

看板C_and_CPP (C/C++)作者 (AzureBlaze)時間13年前 (2013/06/10 18:22), 編輯推噓1(1010)
留言11則, 1人參與, 最新討論串2/2 (看更多)
※ 引述《karaokstar (卡拉歐科史達)》之銘言: > typedef pair<vector<int>, double> PAIR; > 我後來想說如果改成用 vector< PAIR > 來存 > 然後 vector.reserve() 是否可以達到一樣的效果? > 但是我在 reserve(max_size()) 時, 他不給我reserve, 我想說vector是連續空間 > 應該比較沒有fragmentation的問題? > 如果沒有reserve, 直接用vector.pushback() 存, 是存到 11958657 個之後程式就會停止 > 除了自己寫allocator之外有其他方法嗎? > 謝謝 vector<int>裡頭的實做大概是長這樣 class IntVector{ int *data; int capacity; } data指向一塊至少放得下所有元素的記憶體 capacity是這塊記憶體能夠容納的最大元素量 所以當你把一堆vector放到連續記憶體的時候,其實只有上面的部份是連續的 實際的內容還是存在其他地方 vector.push_back()其實是沒什麼效率的事情 IntVector::push_back(int value){ if(size == capacity){ int* newData = new int[capacity*2]; memcpy(newData,data,sizeof(int) * capcity); delete [] data; data = newData; capacity *= 2; } data[size] = value; size++; } 也就是說元素數量超過能夠容納的數量時 他會要一塊更大(通常是兩倍)的記憶體,然後把東西搬過去 所以當你一個一個push_back()時他會慢慢由小要到大 要解決這個就先reserve()你要的大小 不要reserve(max_size()) max_size()只是理論極限,不代表能夠實際達到 ============= 實際上要怎麼解決這個問題要看你到底是怎麼用的 最好先判斷到底是哪裡出問題 可以用 try{ vector.push_back(); }catch(std::exception &e){ cout << e.what(); } 讓他印出stl的錯誤訊息,而不是直接關掉 讀入vector<int>的時候如果能夠預先知道總大小就先reserve 也可以想辦法讓產生資料的地方先讓你知道大小 如果資料實在太多筆,vector塞不下 那你可以試著實做自己的vector (可能要做memory pool) 如果資料不用全部放在記憶體裡,你可以先把他們寫回硬碟 (第1~1000筆在 1.tmp,etc...) 要用的時候再讀回來 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 118.168.57.6

06/10 19:19, , 1F
謝謝回文! 我忘記vector size不夠會直接要兩倍
06/10 19:19, 1F

06/10 19:20, , 2F
然後因為要跑完程式才會知道總大小, 所以我之前跑其他
06/10 19:20, 2F

06/10 19:20, , 3F
測資時都沒reserve, 也沒遇到問題, 因為大概最多存百萬
06/10 19:20, 3F

06/10 19:26, , 4F
我剛剛用try&catch, message印出 allocationbad
06/10 19:26, 4F

06/10 19:31, , 5F
得到的資料要再按照它們的value排序, 目前想到比較簡單
06/10 19:31, 5F

06/10 19:33, , 6F
的方法是分成兩個vector存, 再想辦法 sort 它們
06/10 19:33, 6F

06/10 19:37, , 7F
我原本用 set 是因為有 custom comparison function
06/10 19:37, 7F

06/10 19:38, , 8F
可以照我所希望的排序, 但沒想到八百多萬筆就出問題了
06/10 19:38, 8F

06/10 19:47, , 9F
剛剛又跑了一次 reserve(14000000) 會bad allocation
06/10 19:47, 9F

06/10 19:49, , 10F
reserve(20000000); 沒跑出exception, 程式直接停止 囧
06/10 19:49, 10F

06/10 19:53, , 11F
這種情況就跟一開始用 set 的情況一樣 @@
06/10 19:53, 11F
文章代碼(AID): #1HjQZIqR (C_and_CPP)
文章代碼(AID): #1HjQZIqR (C_and_CPP)