Qt中delete的問題

2021-07-17 03:24:52 字數 2445 閱讀 1856

最近專案遇到了乙個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呼...