欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談QT內(nèi)存泄漏

 更新時間:2021年09月24日 10:19:01   作者:yhl_sophia  
本文主要介紹了淺談QT內(nèi)存泄漏,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

01前言

   前幾天,項目開展了一次代碼初次評審。會上,領(lǐng)導指出一些可能會帶來內(nèi)存泄漏的代碼,如下圖所示:

圖中的pLayout在new的時候沒有指定任何父對象,且MainWindow的析構(gòu)函數(shù)中也沒有對pLayout做delete操作,這意味著為pLayout申請的內(nèi)存空間在程序運行期間是一直沒有得到釋放的。實際上,項目代碼中,還有許多這種“隱患”:一個單例類的成員變量在new的時候沒有指定父對象、一個靜態(tài)類的成員在new的時候沒有指定父對象……

這些“隱患”為何在目前程序運行時沒有暴露出問題?基于這個疑惑,我研究了QT的半自動化的內(nèi)存管理,并結(jié)合實驗進行結(jié)果驗證,現(xiàn)將分析過程記錄下來

02 QT半自動化內(nèi)存管理要點

  • QObject及其派生類的對象,如果其parent非0,那么其parent析構(gòu)時會析構(gòu)該對象
  • QWidget及其派生類的對象,可以設置 Qt::WA_DeleteOnClose 標志位(當close時會析構(gòu)該對象)
  • QAbstractAnimation派生類的對象,可以設置 QAbstractAnimation::DeleteWhenStopped
  • QRunnable::setAutoDelete()、MediaSource::setAutoDelete()
  • 父子關(guān)系:父對象、子對象、父子關(guān)系。這是Qt中所特有的,與類的繼承關(guān)系無關(guān),傳遞參數(shù)與parent有關(guān)(基類、派生類,或父類、子類,這是對于派生體系來說的,與parent無關(guān))

03實驗過程詳解

堆空間的內(nèi)存泄漏與改進方法實踐實例

繼承QWidget類的Test類,通過new為其分配內(nèi)存,沒有設置WA_DeleteOnclose屬性且使用完后也沒有delete

實驗結(jié)果:關(guān)閉testWidget窗口后,沒有調(diào)用其析構(gòu)函數(shù)打印“test delete”信息。直到程序結(jié)束之前testWidget的申請的內(nèi)存空間都未被釋放

改進方法A

為testWidget窗口設置Qt::WA_DeleteOnClose屬性

實驗結(jié)果:關(guān)閉testWidget窗口后,調(diào)用了其析構(gòu)函數(shù),內(nèi)存被釋放了

改進方法B

不設置Qt::WA_DeleteOnClose屬性,但是在new完testWidget后,程序退出前調(diào)用testWidget的delete函數(shù)

實驗結(jié)果:關(guān)閉testWidget窗口后,調(diào)用了其析構(gòu)函數(shù),內(nèi)存也被釋放了

實驗結(jié)論:QWidget及其派生類的對象,可以設置 Qt::WA_DeleteOnClose 標志位(當close時會析構(gòu)該對象)或者手動delete來釋放內(nèi)存

??臻g的內(nèi)存實踐實例不采用new,為testWidget分配棧空間,不設置Qt::WA_DeleteOnClose屬性,不手動delete

實驗結(jié)果:關(guān)閉窗口時調(diào)用了testWidget的析構(gòu)函數(shù),內(nèi)存被釋放了

testWidget不采用new創(chuàng)建,直接將對象建議在??臻g,但設置Qt::WA_DeleteOnClose屬性或者使用后delete &testWidget

實驗結(jié)果:程序崩潰了,在第一次嘗試delete testWidget時就出錯

實驗結(jié)論:delete棧上分配的地址會出錯

父對象和子對象析構(gòu)的實踐實例將testWidget的父對象設置為mainwindow

實驗結(jié)果:關(guān)閉窗口后,正常打印析構(gòu)信息。程序退出前,先釋放testWidget的空間,再釋放mainwindow的空間(兩者都是分配到??臻g)

調(diào)整mainwindow和testWidget的構(gòu)造順序

實驗結(jié)果:程序崩潰

分析原因:mainwindow析構(gòu)時會將其子對象testWidget也析構(gòu),但testWidget是分配到??臻g上的,delete棧上的空間會出錯。

將testWidget分配到堆上,指定父對象為mainwindow,并在程序退出前delete mainwindow

實驗結(jié)果:delete mainwindow時,會將testWidget也一并delete

將testWidget作為mainwindow的成員,但在構(gòu)造時不指定父對象,在main函數(shù)中delete mainwindow

實驗結(jié)果:應用程序退出前只有mainwindow被析構(gòu)了

實驗結(jié)論:

  • 析構(gòu)函數(shù)總是出現(xiàn)在對象的生命期結(jié)束之時,靜態(tài)對象在程序運行結(jié)束之時析構(gòu)。
  • 對象的構(gòu)造和析構(gòu)的關(guān)系是棧數(shù)據(jù)結(jié)構(gòu)中的入棧和出棧的關(guān)系。
  • 指定了父對象的子對象,在父對象被析構(gòu)時,會將其一并析構(gòu)掉

Malloc分配的內(nèi)存空間實踐實例

新建一個malloc_class,將malloc_class作為mainwindow的成員,在mallocClass的構(gòu)造函數(shù)里面用malloc申請500M內(nèi)存,在mainwindow放置一個button,點擊button就delete malloc_class,在任務管理器中看500M內(nèi)存是否有被釋放。對于malloc_class的new操作,測試了兩種情況:

new malloc_class時不指定父對象new malloc_class時指定它的父對象為mainwindow

實驗結(jié)果:兩種情況一樣的結(jié)果,點擊button,在delete testWidget后,在testThread中申請的500M空間都沒有被釋放

猜想是不是因為malloc的空間并沒有指定父對象,異想天開的又測試了另外一種情況:直接創(chuàng)建malloc_class時用malloc為其分配內(nèi)存,再在button的槽函數(shù)里delete malloc_class

實驗結(jié)果:程序崩潰了……

查閱資料得知:malloc只能為POD類型數(shù)據(jù)(一個類或結(jié)構(gòu)體通過二進制拷貝后還能保持數(shù)據(jù)不變,具體解釋自查資料)分配內(nèi)存,其他的必須用new分配內(nèi)存。Malloc函數(shù)分配內(nèi)存空間時并不調(diào)用構(gòu)造函數(shù),同樣free函數(shù)再回收空間時也不調(diào)用析構(gòu)函數(shù)。

實驗結(jié)論:malloc分配的內(nèi)存空間都要自己管理,與QT的父子對象同步析構(gòu)沒有關(guān)系。也就是說應該再次明確:指定父對象的并且基于QObject為基類的對象才會同步析構(gòu)

注意:malloc的空間只是一個虛擬內(nèi)存,一定要初始化或者寫數(shù)據(jù)才會有物理內(nèi)存的體現(xiàn)

04總結(jié)

對于在應用程序中不是常駐的對象,應習慣為其指定父對象,或著用完之后手動delete;對于應用程序中常駐的對象,即便在應用程序結(jié)束后操作系統(tǒng)會釋放其使用的內(nèi)存,也不建議隨性new沒有parent的對象??傊B(yǎng)成嚴格處理內(nèi)存分配和釋放內(nèi)存的好習慣,要清楚自己在編碼時使用了哪些內(nèi)存,什么時候需要釋放,不定時關(guān)注程序的內(nèi)存占用率。

到此這篇關(guān)于淺談QT內(nèi)存泄漏的文章就介紹到這了,更多相關(guān)QT內(nèi)存泄漏內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解C++中虛析構(gòu)函數(shù)的作用及其原理分析

    詳解C++中虛析構(gòu)函數(shù)的作用及其原理分析

    這篇文章主要介紹了C++中虛析構(gòu)函數(shù)的作用及其原理分析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • C++軟件添加dump調(diào)試打印日志(推薦)

    C++軟件添加dump調(diào)試打印日志(推薦)

    下面小編就為大家?guī)硪黄狢++軟件添加dump調(diào)試打印日志(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-07-07
  • Qt 儀表盤的實現(xiàn)示例

    Qt 儀表盤的實現(xiàn)示例

    儀表盤在很多汽車和物聯(lián)網(wǎng)相關(guān)的系統(tǒng)中很常用,本文就來介紹一下Qt 儀表盤的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • C++構(gòu)造函數(shù)深度學習

    C++構(gòu)造函數(shù)深度學習

    這篇文章主要為大家詳細介紹了C++構(gòu)造函數(shù),深度學習C++構(gòu)造函數(shù),感興趣的小伙伴們可以參考一下
    2016-08-08
  • Qt實現(xiàn)進程間通信

    Qt實現(xiàn)進程間通信

    這篇文章主要為大家詳細介紹了Qt實現(xiàn)進程間通信,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • 使用C++實現(xiàn)全排列算法的方法詳解

    使用C++實現(xiàn)全排列算法的方法詳解

    本篇文章是對使用C++實現(xiàn)全排列算法的方法進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • c++中的4種類型轉(zhuǎn)化方式詳細解析

    c++中的4種類型轉(zhuǎn)化方式詳細解析

    const_cast該函數(shù)用于去除指針變量的常量屬性,將它轉(zhuǎn)換為一個對應指針類型的普通變量。反過來,也可以將一個非常量的指針變量轉(zhuǎn)換為一個常指針變量
    2013-10-10
  • Qt實現(xiàn)生成指定范圍內(nèi)隨機數(shù)與隨機字符串

    Qt實現(xiàn)生成指定范圍內(nèi)隨機數(shù)與隨機字符串

    這篇文章主要為大家詳細介紹了如何利用Qt實現(xiàn)生成指定范圍內(nèi)隨機數(shù)與隨機字符串,文中的示例代碼簡潔易懂,感興趣的小伙伴可以自己動手嘗試一下
    2023-07-07
  • C++模板以及實現(xiàn)vector實例詳解

    C++模板以及實現(xiàn)vector實例詳解

    模板是為了實現(xiàn)泛型編程,所謂泛型編程,就是指編寫與類型無關(guān)的代碼,下面這篇文章主要給大家介紹了關(guān)于C++模板以及實現(xiàn)vector的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • C語言實現(xiàn)靜態(tài)順序表的實例詳解

    C語言實現(xiàn)靜態(tài)順序表的實例詳解

    這篇文章主要介紹了C語言實現(xiàn)靜態(tài)順序表的實例詳解的相關(guān)資料,這里提供是幫助大家學習理解這部分內(nèi)容,需要的朋友可以參考下
    2017-08-08

最新評論