最近專案遇到了乙個bug,壓力測試ui總會崩潰,gdb除錯未果,跑到了庫函式,無從查起:
(gdb)bt
#0 0x4146b1e4 in qwidgetprivate::drawwidget(qpaintdevice*, qregion const&,qpoint const&, int, qpainter*, qwidgetbackingstore*) () from/qt/lib/libqt5widgets.so.5
#1 0x4146bb70 in qwidgetprivate::paintsiblingsrecursive(qpaintdevice*,qlistconst&, int, qregion const&, qpoint const&,int, qpainter*, qwidgetbackingstore*) ()
from /qt/lib/libqt5widgets.so.5
#2 0x4146b22c in qwidgetprivate::drawwidget(qpaintdevice*, qregion const&,qpoint const&, int, qpainter*, qwidgetbackingstore*) () from/qt/lib/libqt5widgets.so.5
#3 0x41443918 in qwidgetbackingstore::sync() () from /qt/lib/libqt5widgets.so.5
#4 0x41462c9c in qwidgetprivate::syncbackingstore() () from/qt/lib/libqt5widgets.so.5
#5 0x4146de64 in qwidget::event(qevent*) () from /qt/lib/libqt5widgets.so.5
#8 0x00922918 in ?? ()
#9 0x00922918 in ?? ()
backtracestopped: previous frame identical to this frame (corrupt stack?)
(gdb)
後來發現問題是qt中使用delete出錯,
if(p)
摘錄其中一文片段如下:
qt有一套**記憶體的機制,主要的規則如下:
1、所有繼承自qobject類的類,如果在new的時候指定了父親,那麼它的清理時在父親被delete的時候delete的,所以如果乙個程式中,所有的qobject類都指定了父親,那麼他們是會一級級的在最上面的父親清理時被清理,而不用自己清理;(注:這裡是在new出來物件的時候,這樣依靠qobject釋放的記憶體一點問題沒有,如果以下這種起情況,那麼程式會崩潰
?
1
2
3
qobject derver;
qobject base;
derver.setparent(&base);
兒子和父親都是棧空間上,釋放記憶體時候,先釋放父親,釋放
父親空間的時候,已經把兒子的記憶體釋放了,當釋放兒子的記憶體的是否,會出現記憶體錯誤,因為兒子被釋放了兩次)
3、如果我們自己釋放掉設定qobject為自己父親的類物件,那個指向的父親的qobject會從自己的兒子列表中把這個兒子刪除掉,就不會出現兒子的記憶體會被釋放兩次,如果我們要刪除有這種關係的qobject類的話,正常情況,這樣它會將這個兒子移出它的列表,並且重新構建顯示內容,但是直接這樣做時有風險的!
4、當乙個qobject正在接收事件佇列時如果中途被你delete掉了,就會出現問題了,所以qt中建議大家不要直接delete掉乙個 qobject,如果一定要這樣做,要使用qobject的deletelater()函式,它會讓所有事件都傳送完一切處理好後馬上清除這片記憶體,而且就算呼叫多次的deletelater也不會有問題。
5、qt不建議在乙個qobject 的父親的範圍之外持有對這個qobject的指標,因為如果這樣外面的指標很可能不會察覺這個qobject被釋放,會出現錯誤,如果一定要這樣,就要記住你在哪這樣做了,然後抓住那個被你違規使用的qobject的destroyed()訊號,當它沒有時趕快置零你的外部指標。當然我認為這樣做是及其麻煩也不符合高效率程式設計規範的,所以如果要這樣在外部持有qobject的指標,建議使用引用或者用智慧型指標,如qt就提供了智慧型指標針對這些情況,見最後一條。
6、qt中的智慧型指標封裝為qpointer類,所有qobject的子類都可以用這個智慧型指標來包裝,很多用法與普通指標一樣
(某些記憶體洩露的檢測工具會認為qt的程式因為這種方式存在記憶體洩露,大家不必理會)
還有乙個記憶體洩漏的問題:
class readoutdisplay : public qwidget ;
readoutdisplay::readoutdisplay(qwidget *parent, qstring type) :
qwidget(parent)}
Qt中delete的問題
最近專案遇到了乙個bug,壓力測試ui總會崩潰,gdb除錯未果,跑到了庫函式,無從查起 gdb bt 0 0x4146b1e4 in qwidgetprivate drawwidget qpaintdevice qregion const qpoint const int,qpainter qwid...
QT中什麼時候delete
在c 中學習過程中,我們都知道 qt作為c 的庫,顯然是不會違背c 的前述原則的。可是 注 本文暫不涉及智慧型指標 smart pointer 相關的東西,你可以考慮 qt 智慧型指標學習 一文 在qt中,以下情況下你new出的物件你可以不用 親自去delete 但你應該清楚delete在何處被qt...
從 Qt 的 delete 說開來
在c 中學習過程中,我們都知道 qt作為c 的庫,顯然是不會違背c 的前述原則的。可是 注 本文暫不涉及智慧型指標 smart pointer 相關的東西,你可以考慮 qt 智慧型指標學習 一文 在qt中,以下情況下你new出的物件你可以不用親自去delete 但你應該清楚delete在何處被qt呼...