[問題] bad_alloc 記憶體不足?

看板C_and_CPP (C/C++)作者時間13年前 (2012/07/26 16:41), 編輯推噓3(3041)
留言44則, 4人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) BCB 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) 問題(Question): 我需要開一個4維的陣列,但是卻一直跳出bad_alloc 程式碼(Code):(請善用置底文網頁, 記得排版) int ****H; int Hlenth=1000; H=new int *** [Hlenth]; for(int i=0;i<Hlenth;i++) { H[i]=new int **[Hlenth]; for(int j=0;j<Hlenth;j++) { H[i][j]=new int *[360]; /*for(int k=0;k<360;k++) { H[i][j][k]=new int; for(int l=0;l<1;l++) { H[i][j][k][l]=0; } }*/ } } 上述的程式碼可以正常執行,記憶體的損耗執行前可用記憶體2850mb, 執行後為1480mb,損耗為1370mb,跟用手算4bytes*1000*1000*360/1024/1024=1373mb 結果差不多,但若把最裡層的註解拿掉,程式就沒辦法正常配置記憶體, 會出現bad_alloc,但配置記憶體的大小一樣是1373mb不是嗎? 計算式為 4bytes*1000*1000*360*1/1024/1024=1373mb 我有那裡想錯了嗎? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.118.141.34

07/26 16:50, , 1F
new int...沒用過
07/26 16:50, 1F

07/26 16:50, , 2F
new int[1]這樣吧?
07/26 16:50, 2F

07/26 16:55, , 3F
喔可以這樣用...我看看是出什麼問題
07/26 16:55, 3F

07/26 16:56, , 4F
看裡面的 loop 應該是要 H[i][j][k]=new int[2];
07/26 16:56, 4F

07/26 16:57, , 5F
你的最後一層廻圈存取到不該存取的值
07/26 16:57, 5F

07/26 16:58, , 6F
我打太快了 loop裡面是1沒錯
07/26 16:58, 6F
※ 編輯: sd016808 來自: 140.118.141.34 (07/26 16:58)

07/26 16:59, , 7F
只有1的話幹嘛還弄4維?弄3維不就好了?
07/26 16:59, 7F

07/26 17:00, , 8F
我本來是要開20 但是出現bad_alloc 所以我想說開小一點
07/26 17:00, 8F

07/26 17:00, , 9F
測試 結果發現竟然連開1 都會出現bad_alloc
07/26 17:00, 9F

07/26 17:01, , 10F
我以為開1配置空間應該不會變 但是實際上工作管理員裡
07/26 17:01, 10F

07/26 17:02, , 11F
顯示的可用記憶體大小 卻瞬間幾乎被吃光
07/26 17:02, 11F

07/26 17:03, , 12F
疑!!看到 keyword,吃到>1373mb了..你的 os/memory 是?
07/26 17:03, 12F

07/26 17:03, , 13F
win7 64bit memory為4g
07/26 17:03, 13F

07/26 17:04, , 14F
我這邊12GB win7 64bit一樣爆掉,我想是別的問題
07/26 17:04, 14F

07/26 17:05, , 15F
實際上我這邊測試是吃到2GB多然後就掛了
07/26 17:05, 15F

07/26 17:06, , 16F
你要注意每次 new 其實是有 overhead 的
07/26 17:06, 16F

07/26 17:06, , 17F
那個..大型記憶體特性除了和os相關,也和compiler相關.
07/26 17:06, 17F

07/26 17:06, , 18F
這裡你一共做了 1+1000+1000^2+1000^2*360 = 約 361M 次 new
07/26 17:06, 18F

07/26 17:07, , 19F
這些 overhead 也會多吃你一點記憶體
07/26 17:07, 19F

07/26 17:08, , 20F
還有這支實際上不是只吃1.37g,而是到了 1.8g 左右
07/26 17:08, 20F

07/26 17:08, , 21F
total = 4+1000*4+1000*1000*4+1000*1000*360*1*4+
07/26 17:08, 21F

07/26 17:09, , 22F
那請教為什麼我這邊會爆掉? 我有12GB的RAM
07/26 17:09, 22F

07/26 17:09, , 23F
1000*1000*360*4 , 大概這麼多吧...
07/26 17:09, 23F

07/26 17:10, , 24F
@black:你的compiler是??先看看sizeof(size_t)多大
07/26 17:10, 24F

07/26 17:12, , 25F
4 我剛剛想到我還在用32bit的g++所以應該問題在這
07/26 17:12, 25F

07/26 17:13, , 26F
換用64bit的compile編看看?
07/26 17:13, 26F

07/26 17:14, , 27F
是的, 那便是問題了,重算過,這裡實際大小是 2.686GB
07/26 17:14, 27F

07/26 17:16, , 28F
設欲配置 w[1000,1000,360,1],大小算法如下 :
07/26 17:16, 28F

07/26 17:16, , 29F
****w = 4 ; ***w = 4*1000 (w[1000]);
07/26 17:16, 29F

07/26 17:17, , 30F
**w = 4*10^6 (w[1000][1000]);
07/26 17:17, 30F

07/26 17:18, , 31F
*w = 4*360*10^6 (w[1000][1000][360])
07/26 17:18, 31F

07/26 17:18, , 32F
w = 4*360*10^6*1 (w[1000][1000][360][1])
07/26 17:18, 32F

07/26 17:19, , 33F
這五層加起來就是答案了, 所以暴 2GB,試自己用一維換算吧.
07/26 17:19, 33F

07/26 17:19, , 34F
我試了一下sizeof(size_t) 回傳結果為4 byte 所以我得
07/26 17:19, 34F

07/26 17:21, , 35F
更換成64bit的compiler 才有辦法開 受教了^^
07/26 17:21, 35F

07/26 17:23, , 36F
我沒記錯的話g++ 64bits sizeof(size_t)=8無誤,但vc=4 orz
07/26 17:23, 36F

07/26 17:24, , 37F
所以原 po 要解決這問題的話還要確定 bcb 該版本的大小
07/26 17:24, 37F

07/26 17:27, , 38F
我似乎得更換bcb版本才能繼續做下去了...
07/26 17:27, 38F

07/26 17:29, , 39F
那個..我該說,如果你最終是要配w[1000][1000][360][20],
07/26 17:29, 39F

07/26 17:29, , 40F
即使用一維方式配置,出來大小也是26gb,目前即使win64,單一
07/26 17:29, 40F

07/26 17:30, , 41F
程序最大配給只到 16/20gb, 所以你該考慮的不再是換版本,
07/26 17:30, 41F

07/26 17:30, , 42F
而是考慮換個演算法,或考慮寫到檔案、資料料讀取(速度慢).
07/26 17:30, 42F

07/26 17:32, , 43F
了解! 我試著想看看能不能換方法寫
07/26 17:32, 43F

07/26 17:33, , 44F
感謝E大的幫忙 真的學到了很多之前不知道的事情
07/26 17:33, 44F
文章代碼(AID): #1G4GBFRX (C_and_CPP)
文章代碼(AID): #1G4GBFRX (C_and_CPP)