最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

01前言

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

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

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

02 QT半自動(dòng)化內(nèi)存管理要點(diǎn)

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

03實(shí)驗(yàn)過程詳解

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

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

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

改進(jìn)方法A

為testWidget窗口設(shè)置Qt::WA_DeleteOnClose屬性

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

改進(jìn)方法B

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

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

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

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

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

testWidget不采用new創(chuàng)建,直接將對(duì)象建議在棧空間,但設(shè)置Qt::WA_DeleteOnClose屬性或者使用后delete &testWidget

實(shí)驗(yàn)結(jié)果:程序崩潰了,在第一次嘗試delete testWidget時(shí)就出錯(cuò)

實(shí)驗(yàn)結(jié)論:delete棧上分配的地址會(huì)出錯(cuò)

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

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

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

實(shí)驗(yàn)結(jié)果:程序崩潰

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

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

實(shí)驗(yàn)結(jié)果:delete mainwindow時(shí),會(huì)將testWidget也一并delete

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

實(shí)驗(yàn)結(jié)果:應(yīng)用程序退出前只有mainwindow被析構(gòu)了

實(shí)驗(yàn)結(jié)論:

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

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

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

new malloc_class時(shí)不指定父對(duì)象new malloc_class時(shí)指定它的父對(duì)象為mainwindow

實(shí)驗(yàn)結(jié)果:兩種情況一樣的結(jié)果,點(diǎn)擊button,在delete testWidget后,在testThread中申請(qǐng)的500M空間都沒有被釋放

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

實(shí)驗(yàn)結(jié)果:程序崩潰了……

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

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

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

04總結(jié)

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

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

相關(guān)文章

  • C++中的局部變量、全局變量、局部靜態(tài)變量、全局靜態(tài)變量的區(qū)別

    C++中的局部變量、全局變量、局部靜態(tài)變量、全局靜態(tài)變量的區(qū)別

    本文主要介紹了C++中的局部變量、全局變量、局部靜態(tài)變量、全局靜態(tài)變量的區(qū)別。具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02
  • Linux下C語(yǔ)言修改進(jìn)程名稱的方法

    Linux下C語(yǔ)言修改進(jìn)程名稱的方法

    這篇文章主要介紹了Linux下C語(yǔ)言修改進(jìn)程名稱的方法,涉及Linux下使用C語(yǔ)言操作進(jìn)程的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • Qt實(shí)現(xiàn)簡(jiǎn)易計(jì)時(shí)器的示例代碼

    Qt實(shí)現(xiàn)簡(jiǎn)易計(jì)時(shí)器的示例代碼

    計(jì)時(shí)器實(shí)現(xiàn)四個(gè)功能:開始計(jì)時(shí)、停止計(jì)時(shí)、暫停計(jì)時(shí)以及打點(diǎn)。當(dāng)點(diǎn)擊暫停時(shí),開始按鈕和停止按鈕無法點(diǎn)擊。當(dāng)點(diǎn)擊停止時(shí),開始按鈕和暫停按鈕無法點(diǎn)擊,此時(shí)停止按鈕變?yōu)榍辶?。本文將用Qt實(shí)現(xiàn)這樣的一個(gè)計(jì)時(shí)器,需要的可以參考一下
    2022-06-06
  • C++實(shí)現(xiàn)LeetCode(90.子集合之二)

    C++實(shí)現(xiàn)LeetCode(90.子集合之二)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(90.子集合之二),本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • c語(yǔ)言 sscanf,scanf,fscanf正則表達(dá)式用法

    c語(yǔ)言 sscanf,scanf,fscanf正則表達(dá)式用法

    每種語(yǔ)言都對(duì)正則表達(dá)式有著不同程度的支持,在C語(yǔ)言中,有輸入功能的這三個(gè)函數(shù)對(duì)正則表達(dá)式的支持并不強(qiáng)大,但是我們還是有必要了解一下
    2018-04-04
  • VS2022永久配置OpenCV開發(fā)環(huán)境的實(shí)現(xiàn)

    VS2022永久配置OpenCV開發(fā)環(huán)境的實(shí)現(xiàn)

    本文主要介紹了VS2022永久配置OpenCV開發(fā)環(huán)境的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • C++ 輸入scanf()和輸出printf()的操作

    C++ 輸入scanf()和輸出printf()的操作

    這篇文章主要介紹了C++ 輸入scanf()和輸出printf()的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • C/C++中文件的隨機(jī)讀寫詳解及其作用介紹

    C/C++中文件的隨機(jī)讀寫詳解及其作用介紹

    這篇文章主要介紹了C/C++中文件的隨機(jī)讀寫詳解及其作用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • 對(duì)C語(yǔ)言中sizeof細(xì)節(jié)的三點(diǎn)分析介紹

    對(duì)C語(yǔ)言中sizeof細(xì)節(jié)的三點(diǎn)分析介紹

    以下是對(duì)C語(yǔ)言中sizeof的細(xì)節(jié)進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下
    2013-07-07
  • C++ Sort函數(shù)使用場(chǎng)景分析

    C++ Sort函數(shù)使用場(chǎng)景分析

    sort函數(shù)是algorithm庫(kù)下的一個(gè)函數(shù),sort函數(shù)是不穩(wěn)定的,即大小相同的元素在排序后相對(duì)順序可能發(fā)生改變,如果某些場(chǎng)景需要保持相同元素間的相對(duì)順序,可使用stable_sort函數(shù),接下來通過本文給大家介紹C++ Sort函數(shù)詳解,感興趣的朋友一起看看吧
    2025-04-04

最新評(píng)論

海兴县| 射阳县| 固阳县| 新郑市| 博罗县| 龙川县| 巍山| 昌宁县| 泾川县| 遂昌县| 阿荣旗| 马龙县| 龙江县| 合水县| 彭州市| 清水河县| 罗平县| 喀喇沁旗| 广德县| 牟定县| 阜城县| 唐山市| 诸城市| 巩留县| 宜兰市| 泊头市| 二连浩特市| 晋中市| 太仆寺旗| 扬州市| 廊坊市| 卢湾区| 海城市| 宽甸| 梁河县| 东阿县| 锡林浩特市| 纳雍县| 新乐市| 洛南县| 渭南市|