半天時間找到原因卻仍未解決的bug
在乙個巨大的資料檔案作為輸入時, 出現了乙個assert斷言錯誤.
花了半天時間跟蹤**, 費盡心思找到了錯誤的**,
可是一時間也沒有解決的辦法, 只能打個臨時補丁.
類裡面有個成員變數
std::ofstream m_ofs;
在某個方法裡面的斷言警告:
assert(!m_ofs);
流操作之後都有乙個狀態判斷:
if (!m_ofs)
為什麼會有錯誤的流狀態?
但是open()操作後判斷失敗沒有關閉流.
m_ofs.open(spath);
if (!m_of)
表面上看是ofstream::open()開啟檔案出錯了.
open()出錯時只寫了一條日誌, 沒做處理.
這個ofstream物件m_ofs不是臨時物件, 而是類內嵌物件.
下一次使用時, 發現m_ofs處於已開啟狀態, 而流狀態是錯誤的,
以為open()失敗後檔案會處於關閉狀態, 看來是錯誤的.
open()失敗後加了乙個close()試了試,還是有流錯誤。
open()為什麼會出錯? strerror(errno)顯示"no error".
以為是errno沒有正確指示錯誤, 再跟蹤進入open()**, 發現open()其實是成功了.
m_ofs是在open()之前就已經fail了(檢視內部狀態state=2, 即failbit位).
一定是上次close()後failbit並沒有清除.
close()成功情況下, 會執行clear(), 但有可能close()失敗.
新增clear()在所有close()之前.
可是failbit象是憑空出現, clear()並沒有起作用.
回憶歷史**, 原來只有臨時變數的流, 用完就自動關閉了.
而為了對付頻繁的同一檔案開啟, 流物件改為了內部成員變數.
而流的宿主類間接地是另乙個類的成員變數, 該類是某stl容器類的元素.
問題就在這裡了, stl容器類會使用其元素類的拷貝建構函式來複製元素.
一定是ofstream通過這樣的複製後產生了錯誤的狀態.
而宿主類及其上層也沒有提供拷貝建構函式, 只有預設的淺拷貝.
如果沒有這個流, 這些類都是一些簡單資料類, 完全可以使用預設的位元組拷貝.
淺拷貝不行, 深拷貝不能, 結果是找到原因, 卻不知如何修改.
只能暫時恢復為臨時流變數.
不過最終還應該支援大量的檔案開啟關閉操作, 不知怎麼辦.
心得:
* 沒有必要就不要儲存乙個流變數,使用臨時變數可保證檔案開啟與關閉是成對的。
* stl容器最好只存放簡單資料,可避免自定義拷貝建構函式。
如果元素類較複雜,應考慮使用指標,因為有可能今後的修改後使元素類更複雜。
* ofstream::close()可能不會清除錯誤狀態,並可能置failbit,如未開啟就關閉。
上面的clear()應加在close()之後。
問題:* 如何新增單元測試,使得乙個類保證為簡單資料類,或保證stl容器可安全使用?
* 不能實現深拷貝時,有沒有辦法解決淺拷貝問題?
這是標題啊,找了半天沒找到
健康博文在瞎寫嘛?主題呢?團隊協作幹專案 回歸混沌 太極 學以致用 兩儀 效率 產品 產能 產出 三才 生活 工作 價值 成就感 喜悅感 幸福感 四象 太陰 太陽 少陰 少陽?五行 金 木 水 火 土 六合 十二生肖六合?七星 樞 天璇 天璣 天權 玉衡 開陽 搖光?八卦 幹天,坤地,坎水,離火,震...
mysql當天時間和前一天時間
獲取當前的年月日,我使用的是 curdate 下一天或者前一天 curdate 1curdate 1 這是錯誤的寫法 mysql官網也是不承認時間直接相加減的,雖然會將當前時間轉換為20160802,這時候就是比較這一串字元,mysql官網是不承認用這種方式比較時間大小的正確的sql語句 selec...
肯定搜了半天才找到這裡吧
名稱 規格型號 主計量主數量 廠商板卡 cpci429 16t16r 6495 122 423 423件1 ballard 線纜 10ft雙頭pl75短截線 16014件4 ballard 4頭匯流排耦合器 17014件4 ballard a429 usb 8r4t cp ua1430件1 ball...