Re: [問題] fscanf讀txt檔大量數值錯誤問題

看板C_and_CPP作者 (raise(11))時間11年前 (2014/03/18 16:53), 編輯推噓2(2016)
留言18則, 2人參與, 最新討論串2/2 (看更多)
原來的作法是: int **data; data = (int**)new char [height * sizeof(int *) + width * height * sizeof(int)]; for (i = 0; i < height; i++) data[i] = (int *)data + height + i * width; 其中這一行 data[i] = (int *)data + height + i * width; 在64位元的電腦應該會造成記憶體出問題,假設sizeof(int)是4而sizeof(int*)是8, (int*)data+1和(int*)(data+1)是不一樣的。 前者加sizeof(int)後者加sizeof(int*) ,因為data是int**。 所以可以考慮改成: data[i] = (int*)data + height*(sizeof(int*)/sizeof(int)) + i * width; 另一種作法,利用sizeof(char)是一個byte: ddata[i] = (int*)((char*)(data + height) + i * width * sizeof(int)); 總而言之,記憶體爬格子是個需要小心的工作... 越來越多電腦買來的時候就是裝64位元的,所以這類的狀況應該滿容易碰到。 另外一件事就是,記憶體配置錯誤還是可能寫值進去,而且電腦沒報錯。 可能的原因包括測試的迴圈被最佳化忽略掉,或者剛好被覆寫的記憶體沒被使用等。 這些只是根據原PO提供的資訊所作的猜測,如果code原本已經是正確寫法, 或者確定coding的環境沒有這個問題,那可以直接忽略我這一篇。 -- 謝謝uranusjr提供的highlighter http://bbshighlighter.uranusjr.com/ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.249.181.204

03/18 18:37, , 1F
若是64位元電腦,可能是發生資料錯亂,而不是堆積損毁程式掛掉;
03/18 18:37, 1F

03/18 18:38, , 2F
反而是32位元電腦搭上double,造成後面資料讀超出配置範圍掛掉.
03/18 18:38, 2F

03/18 21:36, , 3F
不知道yvb說的堆積損和資料錯亂的差別?不過在我x64 linux上
03/18 21:36, 3F

03/18 21:38, , 4F
是segmentation fault,遞迴data[x]就會寫到錯誤位址了
03/18 21:38, 4F

03/18 21:38, , 5F
再deref就會seg fault
03/18 21:38, 5F

03/18 22:08, , 6F
雖然用debugger就可以,我還是寫了一個測試
03/18 22:08, 6F

03/18 22:08, , 7F

03/18 22:29, , 8F
阿遞迴應該說迭代,錯誤中文用詞
03/18 22:29, 8F

03/19 12:44, , 9F
抱歉, 一時沒想清楚, 以為64位元搭配int只是指標指的範圍太小,
03/19 12:44, 9F

03/19 12:45, , 10F
在data內重疊, 可能重覆蓋寫資料, 造成資料錯亂而已; 沒考慮到
03/19 12:45, 10F

03/19 12:45, , 11F
讀取資料時, 會蓋寫到 data[i], 而可能讓 data[i] 指向錯誤;
03/19 12:45, 11F

03/19 12:45, , 12F
當然, 若運氣超好, 讀進 (&data[i]) 的資料值恰巧指向合法位址
03/19 12:45, 12F

03/19 12:46, , 13F
也可能純粹搞亂資料而已, 而未造成 segfault.
03/19 12:46, 13F

03/19 12:46, , 14F
相對32位元搭配double, 則是在設定 data[i] 指標時就超出範圍;
03/19 12:46, 14F

03/19 12:46, , 15F
但如果在讀入 data 前又額外配置記憶體, 也可能後續的讀取只是
03/19 12:46, 15F

03/19 12:47, , 16F
蓋寫後來配置區域的資料, 而不會發生 segfault.
03/19 12:47, 16F

03/19 12:47, , 17F
至於堆積損毁, 其實是原PO附圖中的詞, 也就是heap corruption,
03/19 12:47, 17F

03/19 12:48, , 18F
有幾種情況, 其中之一就是指標錯誤又去存取資料而發生的.
03/19 12:48, 18F
文章代碼(AID): #1JA0cH-B (C_and_CPP)
文章代碼(AID): #1JA0cH-B (C_and_CPP)