[問題] free時出現錯誤?

看板C_and_CPP (C/C++)作者 (K.L)時間14年前 (2011/09/12 06:08), 編輯推噓3(3051)
留言54則, 4人參與, 最新討論串1/1
想再請問一下 int size = 10; float *M_1; M_1=(float *)calloc(size+1,sizeof(float)); 然後中間過程中都只做 M_1[X] X->0~size 只對其做取值、放入新值,加減乘的動作 最後做 free(M_1); 有什麼特殊情況會導致 中間執行中無誤,反而在free時會錯呢? 謝謝 感謝 VictorTom 詳細的說明 -> C語言沒有對array邊界或pointer的存取做太多檢查 Ex: 假如你動態要了ABC三塊記憶體, 結果在A用超過寫壞了 不該寫的地方, 比如恰好把BC的管理區塊寫壞了, 那麼你會 在free BC的時候才發現error跳出來, 但實際上問題根本是 發生在存取A的時候. ------------------------------------------------------------- 開發平台(Platform): (Ex: VC++, GCC, Linux, ...) VS 2008 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) no 問題(Question): free資料時跳出錯誤訊息 http://ppt.cc/ZXkP 餵入的資料(Input): Dimension = 2; DataSheet =10000; 預期的正確結果(Expected Output): 可以正常free掉結束程式 錯誤結果(Wrong Output): free顯示錯誤 程式碼(Code):(請善用置底文網頁, 記得排版) float *Dimension_1; float *Dimension_2; float *M_1; float *M_2; float *M_3; float *M_4; float *M_5; float *M_6; float *temp_1; float *temp_2; float *temp_3; float *temp_4; float *temp_5; float *temp_6; //中間讀檔過程使用 Dimension_1 & Dimension_2 已檢查無誤 int MAX=4; long int size = DataSheet*MAX+2; // DataSheet = 10000 M_1=(float *)calloc(size+1,sizeof(float)); M_2=(float *)calloc(size+1,sizeof(float)); M_3=(float *)calloc(size+1,sizeof(float)); M_4=(float *)calloc(size+1,sizeof(float)); M_5=(float *)calloc(size+1,sizeof(float)); M_6=(float *)calloc(size+1,sizeof(float)); temp_1 = (float *)calloc(size+1,sizeof(float)); temp_2 = (float *)calloc(size+1,sizeof(float)); temp_3 = (float *)calloc(size+1,sizeof(float)); temp_4 = (float *)calloc(size+1,sizeof(float)); temp_5 = (float *)calloc(size+1,sizeof(float)); temp_6 = (float *)calloc(size+1,sizeof(float)); for (long int i = 0 ; i < size+1 ; i++) { // printf("i =%d\n",i); M_1[i]=-1; M_2[i]=-1; M_3[i]=-1; M_4[i]=-1; M_5[i]=-1; M_6[i]=-1; temp_1[i]=-1; temp_2[i]=-1; temp_3[i]=-1; temp_4[i]=-1; temp_5[i]=-1; temp_6[i]=-1; } free(Dimension_1); free(Dimension_2); free(M_1); printf("--------------------------結束 free(M_1) \n"); free(M_2); printf("--------------------------結束 free(M_2) \n"); free(M_3); printf("--------------------------結束 free(M_3) \n"); free(M_4); printf("--------------------------結束 free(M_4) \n"); free(M_5); printf("--------------------------結束 free(M_5) \n"); free(M_6); printf("--------------------------結束 free(M_6) \n"); free(temp_1); free(temp_2); free(temp_3); free(temp_4); free(temp_5); free(temp_6); 補充說明(Supplement): 已經確定運算過程中沒有使用到free,但會在free(M_1); 中斷 若將free(M_1)註解掉,則會變成free(M_2)錯誤 1~6 但 free temp_1~6 不會錯誤,程式中間也沒有出現M_1~M_6存取錯誤 也將中間過程全部註解掉還是會跑出錯誤訊息 錯誤圖片:http://ppt.cc/ZXkP 另外一支程式也是相同架構寫的只有資料算法不同但卻可以free掉 請各位高手幫幫忙@@" 謝謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.116.191.88

09/12 06:11, , 1F
其他 若DataSheet = 1000 100 ..等都可以正常運作
09/12 06:11, 1F

09/12 06:15, , 2F
噢,不對,任意大小都會顯示錯誤@@
09/12 06:15, 2F

09/12 06:22, , 3F
確定是中間free M_1~6有問題,註解掉後程式可正常運作@@
09/12 06:22, 3F

09/12 12:33, , 4F
這種情況通常不是free報錯時的地方有問題, 而可能是你
09/12 12:33, 4F

09/12 12:33, , 5F
用超過動態要來的array, 導致破壞了heap管理的欄位; 只
09/12 12:33, 5F

09/12 12:34, , 6F
是C沒有強制檢查array邊界的設計, 所以等到你要free時
09/12 12:34, 6F

09/12 12:34, , 7F
mem管理機制才發現有問題, 因此跳出error中斷....@_@"
09/12 12:34, 7F

09/12 12:39, , 8F
至於哪裡有問題, 看你方不方便貼code吧; 不然, 把你寫
09/12 12:39, 8F

09/12 12:40, , 9F
沒問題的Dimention_1/2的處理部份全部註解掉試試看先XD
09/12 12:40, 9F

09/12 13:15, , 10F
所以有可能執行過程中M_1~M_6有超過邊界存取@_@?
09/12 13:15, 10F

09/12 13:15, , 11F
然後free時才跳出錯誤,感謝指導,晚上回去試試
09/12 13:15, 11F

09/12 13:34, , 12F
有可能, 只是因為你的code只貼這樣, 所以我還以為M_1~6
09/12 13:34, 12F

09/12 13:34, , 13F
只像現在這樣assign成-1就可以做出error....Orz
09/12 13:34, 13F

09/12 13:35, , 14F
相同的, temp_1~6也最好都檢查一下....
09/12 13:35, 14F

09/12 13:35, , 15F
昨天凌晨試的時候的確只給-1就造成ERROR@ @
09/12 13:35, 15F

09/12 13:36, , 16F
然後除錯除到早上也不知道怎麼辦就跑上來問了
09/12 13:36, 16F

09/12 13:36, , 17F
謝謝!
09/12 13:36, 17F

09/12 13:37, , 18F
有點奇怪, 那個迴圈assign -1看起來沒有越界, 你要不要
09/12 13:37, 18F

09/12 13:37, , 19F
就是註解幾乎剩下上面的程式碼會有FREE時ERROR這樣@@
09/12 13:37, 19F

09/12 13:37, , 20F
先檢查一下每次calloc是不是都有成功拿到address? 雖然
09/12 13:37, 20F

09/12 13:37, , 21F
看起來不至於失敗....
09/12 13:37, 21F

09/12 13:38, , 22F
"//中間讀檔過程使用..." 這邊應該有東西吧? 還有
09/12 13:38, 22F

09/12 13:38, , 23F
嗯,了解@@ 晚上回去再來試試 謝謝!
09/12 13:38, 23F

09/12 13:38, , 24F
?
09/12 13:38, 24F

09/12 13:38, , 25F
Dimension_1/2應該也有calloc/malloc然後使用的code吧?
09/12 13:38, 25F

09/12 13:39, , 26F
有,每一個指標都是這樣做
09/12 13:39, 26F

09/12 13:39, , 27F
建議貼完整的code吧, 如果你只把code砍到這樣還有問題,
09/12 13:39, 27F

09/12 13:40, , 28F
那小弟會覺得Dimension那邊最好檢查一下....@_@"
09/12 13:40, 28F

09/12 13:40, , 29F
還有問題的話...要怎麼辦@@?
09/12 13:40, 29F

09/12 13:40, , 30F
噢噢,知道了 感謝V大熱情指導
09/12 13:40, 30F

09/12 18:01, , 31F
看來應該是中間演算法有出錯QQ 全註解後無誤
09/12 18:01, 31F

09/12 18:02, , 32F
但是為什麼執行過程中不會提醒哪邊錯誤呢? @@?
09/12 18:02, 32F

09/12 18:15, , 33F
一般把他當成陣列用的話,不是應該執行中就會炸了嘛@@?
09/12 18:15, 33F

09/12 18:56, , 34F
假如沒有走到特殊的記憶體位址 是不會炸的...
09/12 18:56, 34F

09/12 19:33, , 35F
特殊的記憶體位址是指?
09/12 19:33, 35F

09/12 19:33, , 36F
只對*M_X 其做取值及放值的動作,為什麼最後會炸呢?
09/12 19:33, 36F

09/12 19:34, , 37F
意思是針對每一個配置的記憶體位址都有初始化了
09/12 19:34, 37F

09/12 19:35, , 38F
初始化的過程也沒有出現中斷,為什麼到最後free時才會斷?
09/12 19:35, 38F

09/12 19:36, , 39F
難道是運算過程中改到了記憶體位址嘛@@?
09/12 19:36, 39F
※ 編輯: kimgtob 來自: 140.116.191.88 (09/12 19:45)

09/12 19:52, , 40F
就說了C語言沒有對array邊界或pointer的存取做太多檢查,
09/12 19:52, 40F

09/12 19:53, , 41F
噢噢,所以沒有辦法像宣告float M_1[10] 一樣,跑跑中斷?
09/12 19:53, 41F

09/12 19:53, , 42F
所以像假如你寫超過動態陣列的範圍寫壞了某塊記憶體區塊
09/12 19:53, 42F
※ 編輯: kimgtob 來自: 140.116.191.88 (09/12 19:54)

09/12 19:53, , 43F
管理的欄位, 那麼等到它要被free時, 管理機制才會發現資
09/12 19:53, 43F

09/12 19:54, , 44F
料有誤, 然後因此跳出exception或error來中斷你的程式.
09/12 19:54, 44F

09/12 19:55, , 45F
瞭解了,感謝幾位的幫忙
09/12 19:55, 45F

09/12 19:56, , 46F
Ex: 假如你動態要了ABC三塊記憶體, 結果在A用超過寫壞了
09/12 19:56, 46F

09/12 19:56, , 47F
不該寫的地方, 比如恰好把BC的管理區塊寫壞了, 那麼你會
09/12 19:56, 47F

09/12 19:57, , 48F
在free BC的時候才發現error跳出來, 但實際上問題根本是
09/12 19:57, 48F

09/12 19:57, , 49F
發生在存取A的時候. 考慮到你說把程式簡化到像你貼的部
09/12 19:57, 49F

09/12 19:58, , 50F
份這樣了還會出錯, 才會懷疑到你以為沒事的Dimension1/2
09/12 19:58, 50F
※ 編輯: kimgtob 來自: 140.116.191.88 (09/12 20:00)

09/12 19:59, , 51F
那邊是不是有寫超過邊界. 貼code與測資會容易釐清些@_@"
09/12 19:59, 51F

09/12 20:02, , 52F
噢噢,先來檢查看看裡面有沒有算錯好了 感謝!
09/12 20:02, 52F

09/12 20:11, , 53F
噢,陣列(M_1~6)給的小了三倍 QQ
09/12 20:11, 53F

09/13 10:23, , 54F
一切都是小三的錯
09/13 10:23, 54F
文章代碼(AID): #1ERJ5d8f (C_and_CPP)
文章代碼(AID): #1ERJ5d8f (C_and_CPP)