一種航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存使用靜態(tài)檢查方法
【專(zhuān)利摘要】本發(fā)明公開(kāi)了一種航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存使用靜態(tài)檢查方法。在航管訓(xùn)練系統(tǒng)中運(yùn)行一個(gè)Qt程序內(nèi)存使用的靜態(tài)檢查程序,運(yùn)行時(shí)將被檢查的代碼所在的目錄作為運(yùn)行參數(shù)。檢測(cè)在5個(gè)模塊中進(jìn)行:遍歷工程目錄和子目錄下的所有.cpp和.h文件,全路徑保存為string類(lèi)型存放到cpp_file中;按行讀取文件每行信息,解析new和delete語(yǔ)句,得到Qt控件對(duì)象的創(chuàng)建信息和所有對(duì)象的刪除信息;解析得到的Qt對(duì)象的創(chuàng)建信息存放在newOBJMap中,刪除信息存放在deleteOBJMap中;遍歷newOBJMap中的每個(gè)元素,在deleteOBJMap中查找對(duì)應(yīng)的元素,存在對(duì)應(yīng)元素將信息合并存放QtObjectMap中,檢測(cè)結(jié)果輸出到日志文件或控制臺(tái)。有效解決了航管訓(xùn)練系統(tǒng)因Qt特殊性帶來(lái)的內(nèi)存泄露問(wèn)題,大幅提高系統(tǒng)安全性、可靠性和實(shí)用性。
【專(zhuān)利說(shuō)明】一種航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存使用靜態(tài)檢查方法 一、 所屬【技術(shù)領(lǐng)域】
[0001] 本發(fā)明涉及航管訓(xùn)練系統(tǒng),特別涉及使用Qt開(kāi)發(fā)的航管系統(tǒng)用戶界面程序的內(nèi) 存使用靜態(tài)檢查。 二、
【背景技術(shù)】
[0002] 航管訓(xùn)練系統(tǒng)除了仿真核心程序以外,還需要大量用戶界面程序完成數(shù)據(jù)準(zhǔn)備、 模擬飛行員操作、受訓(xùn)管制員席位等。在大型的航管訓(xùn)練系統(tǒng)進(jìn)行長(zhǎng)時(shí)間的、復(fù)雜流程的訓(xùn) 練活動(dòng)時(shí),對(duì)人機(jī)界面的穩(wěn)定運(yùn)行提出了較高的要求,如不能出現(xiàn)內(nèi)存泄露、不能中途異常 退出等。本方法對(duì)使用QT開(kāi)發(fā)的人機(jī)界面進(jìn)程的源碼提供靜態(tài)檢查機(jī)制,方便開(kāi)發(fā)人員檢 查錯(cuò)誤,及時(shí)修正缺陷。
[0003] Qt是1991年由奇趣科技開(kāi)發(fā)的跨平臺(tái)C++圖形用戶界面應(yīng)用程序開(kāi)發(fā)框架,Qt 庫(kù)中很多類(lèi)都以QObject作為他們的基類(lèi),QObject的對(duì)象總是以樹(shù)狀結(jié)構(gòu)組織自己。當(dāng) 我們創(chuàng)建一個(gè)QObject對(duì)象時(shí),可以指定其父對(duì)象(也被稱(chēng)為父控件),新創(chuàng)建的對(duì)象將被 加入到父對(duì)象的子對(duì)象(也被稱(chēng)為子控件)列表中。當(dāng)父對(duì)象被析構(gòu)時(shí),這個(gè)列表中的所 有對(duì)象會(huì)被析構(gòu)。不但如此,當(dāng)某個(gè)QOb ject對(duì)象被析構(gòu)時(shí),它會(huì)將自己從父對(duì)象的列表中 刪除,以避免父對(duì)象被析構(gòu)時(shí)再次析構(gòu)自己。
[0004] 由于QObject對(duì)象具有上述析構(gòu)功能,當(dāng)我們使用new操作符在堆中創(chuàng)建Qobject 對(duì)象時(shí),并不需要使用delete操作符析構(gòu)它們。
[0005] 所以編寫(xiě)Qt程序時(shí),開(kāi)發(fā)人員很容易寫(xiě)出內(nèi)存處理不適當(dāng)?shù)某绦驅(qū)е聝?nèi)存泄露。 三、
【發(fā)明內(nèi)容】
[0006] 本發(fā)明的目的旨在解決航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中使用Qt開(kāi)發(fā)人機(jī)界面中,由于Qt程 序特殊性可能帶來(lái)的內(nèi)存泄露問(wèn)題。
[0007] 本發(fā)明的目的是這樣達(dá)到的:一種航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存靜態(tài)檢查方 法,其特征在于:在航管訓(xùn)練系統(tǒng)中運(yùn)行一個(gè)Qt程序內(nèi)存使用靜態(tài)的檢查程序,該程序運(yùn) 行時(shí)將被檢查的代碼所在的目錄作為運(yùn)行參數(shù),目錄可以有子目錄,得到檢測(cè)結(jié)果后,將 監(jiān)測(cè)結(jié)果輸出到日志文件或控制臺(tái)。
[0008] 本方法專(zhuān)門(mén)針對(duì)Qt程序中兩種Qt專(zhuān)屬的兩種內(nèi)存泄露情況提供檢查能力:Qt控 件對(duì)象沒(méi)有父控件,在堆中new 了這個(gè)對(duì)象;Qt控件對(duì)象有父控件。
[0009] 檢測(cè)在如下5個(gè)模塊中進(jìn)行:
[0010] 1)、遍歷工程目錄和子目錄下的所有后綴名為· CPP和· h文件,把文件全路徑保存 為string類(lèi)型,再存放到vector類(lèi)型的cpp_file中;
[0011] 2)、遍歷cpp_file中的每個(gè)文件,按行讀取文件每行信息,解析new和delete語(yǔ) 句,得到Qt控件對(duì)象的創(chuàng)建信息和所有對(duì)象的刪除信息;
[0012] 3)、解析得到的Qt控件對(duì)象的創(chuàng)建信息存放在newOBJMap中,所有對(duì)象的刪除信 息存放在deIeteOBJMap中;
[0013] 4)、遍歷newOBJMap中的每個(gè)元素,在deleteOBJMap中查找對(duì)應(yīng)的元素,如果存在 對(duì)應(yīng)元素,則將信息合并,存放在QtObjectMap中;
[0014] 5)、遍歷QtObjectMap中每個(gè)元素,得到檢測(cè)結(jié)果,輸出到日志文件或控制臺(tái)。
[0015] 所述在1)模塊中進(jìn)行的檢測(cè),是通過(guò)Windows系統(tǒng)提供的_findfirst ()和_ findnext ()函數(shù)遍歷某個(gè)工程文件下的所有文件,并把.h和.cpp文件全路徑名存放在一個(gè) Vector類(lèi)型的cpp_file中,具體步驟是:
[0016] 開(kāi)始,第一步,控制臺(tái)獲取工程目錄,第二步,判斷findfrist獲取當(dāng)前目錄下第一 個(gè)實(shí)例句柄,句柄值為-IL ?是,結(jié)束,否,第三步,findnext根據(jù)_findfirst獲得的句柄遍歷 目錄下的所有實(shí)例,判斷返回值是否為〇 ?是,結(jié)束,否,進(jìn)入第四步,判斷此實(shí)例為子文件 夾嗎?是,當(dāng)前目錄鏈接文件夾名字得到新的目錄,返回第二步,否,進(jìn)入第五步,判斷此實(shí) 例為· cpp或· h文件嗎?是,第六步,將· cpp和· h文件的全名保存到vector類(lèi)型的cpp_ file中,返回第三步。
[0017] 所述在模塊2)中進(jìn)行的檢測(cè)具體步驟是:
[0018] 開(kāi)始,第一步,判斷文件結(jié)束?是,結(jié)束,否,第二步,讀取每行文本,保存在string 類(lèi)型的line中,第三步,判斷l(xiāng)ine為注釋嗎?是,結(jié)束,否,進(jìn)入第四步,判斷是line為new 或delete語(yǔ)句?否,進(jìn)入第五步,判斷是new語(yǔ)句?是,解析line得到的刪除對(duì)象信息,文 件位置更信息,并將得到的信息保存在deleteOBJMap中,返回第一步;是new語(yǔ)句,進(jìn)入第 六步,解析語(yǔ)句獲得創(chuàng)建對(duì)象的類(lèi)別,第七步,根據(jù)類(lèi)別判斷為Qt空間類(lèi)?不是,結(jié)束,是, 第八步,將解析得到的Qt控件,父控件,文件位置信息保存到newOBJMap中,返回第一步。
[0019] 所述在模塊4)中進(jìn)行的檢測(cè)具體步驟是:
[0020] 開(kāi)始,第一步,判斷newOBJMap結(jié)束?是,結(jié)束,否,第二步,獲取newOBJMap的下一 元素,第三步,判斷在deleteOBJMap中找到對(duì)應(yīng)元素?是,第四步,將這兩個(gè)元素合并,保 存到QtObjectMap,結(jié)束;否,把newOBJMap信息保存到QtObjectMap中,無(wú)刪除信息補(bǔ)空, 回復(fù)到第一步。
[0021] 所述在模塊2)進(jìn)行的檢測(cè)具體步驟中第三步,判斷l(xiāng)ine是否為注釋識(shí)別對(duì)象分 為兩種://行注釋?zhuān)?**/段注釋?zhuān)⑨尯痛a區(qū)別對(duì)待,設(shè)置一個(gè)bool變量result區(qū)別該 行代碼是不是注釋即可,Result由解析代碼的函數(shù)返回值更新;
[0022] 若為行注釋?zhuān)苯犹^(guò)該行即可,并設(shè)result為commentEnd,表示注釋結(jié)束;若為 段注釋?zhuān)覜](méi)有在一行中同時(shí)出現(xiàn)/*和*/,則result值為commentBegin,表示注釋開(kāi)始; 若在一行中同時(shí)出現(xiàn)/*和*/,則result值為commentEnd,表示注釋結(jié)束;
[0023] 解析每行代碼時(shí),根據(jù)result值選擇不同的解析函數(shù),parseCommentO為解析注 釋的函數(shù),ParseCodeO為解析代碼的函數(shù);
[0024] 第七步中,根據(jù)類(lèi)別判斷為Qt空間類(lèi)識(shí)別對(duì)象時(shí)分為兩步:
[0025] (1)識(shí)別出程序中創(chuàng)建對(duì)象的語(yǔ)句;
[0026] (2)判斷識(shí)別出的對(duì)象是不是Qt對(duì)象:Qt控件所屬的類(lèi)都是有繼承關(guān)系的,且最 終的父對(duì)象都為QWidget,針對(duì)這種繼承樹(shù)的關(guān)系,通過(guò)讀取InheritTree. ini配置文件建 立一個(gè)樹(shù)的結(jié)構(gòu),樹(shù)結(jié)構(gòu)提供了一個(gè)接口:findChild(string key,P0INTER*p),返回值為指 針p指向樹(shù)中關(guān)鍵字為key的結(jié)點(diǎn),如果樹(shù)中不存在關(guān)鍵字為key的結(jié)點(diǎn),則p的值為NULL, 把某個(gè)類(lèi)名作為實(shí)參傳給key,可判斷此類(lèi)是不是Qt的控件類(lèi)了,即能判斷對(duì)象的對(duì)象是 不是Qt控件對(duì)象。
[0027] 本發(fā)明的積極效果是:有效解決了航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中,使用Qt開(kāi)發(fā)人機(jī)界面 時(shí),因 Qt特殊性可能帶來(lái)的內(nèi)存泄露問(wèn)題,保證系統(tǒng)的安全。由于本發(fā)明方法檢測(cè)后得到 的結(jié)果,輸出到日志文件或控制臺(tái),開(kāi)發(fā)人員可及時(shí)方便地發(fā)現(xiàn)問(wèn)題,及時(shí)修正缺陷。對(duì)提 高航管訓(xùn)練系統(tǒng)自身的可靠性和實(shí)用性有非?,F(xiàn)實(shí)的積極意義。 四、
【專(zhuān)利附圖】
【附圖說(shuō)明】
[0028] 圖1是本發(fā)明Qt程序內(nèi)存使用靜態(tài)檢測(cè)軟件模塊組成圖。
[0029] 圖2是在模塊掃描工程所有· cpp和· h文件流程圖。
[0030] 圖3是讀inheritTree. ini配置文件生成Qt控件類(lèi)的繼承樹(shù)示意圖。
[0031] 圖4是解析每個(gè)文件流程圖。
[0032] 圖 5 是合并 newOBJMap 和 deIeteOBJMap 流程圖。 五、
【具體實(shí)施方式】
[0033] 本發(fā)明專(zhuān)門(mén)針對(duì)航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中使用Qt進(jìn)行人機(jī)界面開(kāi)發(fā)的程序進(jìn)行靜態(tài) 檢查而研究的新方法,解決Qt程序開(kāi)發(fā)中產(chǎn)生的內(nèi)存泄露問(wèn)題。
[0034] 技術(shù)實(shí)現(xiàn)的總思路是專(zhuān)門(mén)針對(duì)Qt開(kāi)發(fā)中兩種Qt專(zhuān)屬的兩種內(nèi)存泄露情況提供檢 查能力:
[0035] 本方法專(zhuān)門(mén)針對(duì)Qt開(kāi)發(fā)中兩種Qt專(zhuān)屬的兩種內(nèi)存泄露情況提供檢查能力:
[0036] Qt控件對(duì)象若沒(méi)有父控件,如果在堆中new 了這個(gè)對(duì)象,那么必須編碼實(shí)現(xiàn)刪除, 否則會(huì)有內(nèi)存泄露;
[0037] Qt控件對(duì)象有父控件,此時(shí)無(wú)需程序員手動(dòng)delete這個(gè)Qt控件,因?yàn)楦缚丶谖?構(gòu)時(shí),會(huì)自動(dòng)析構(gòu)自己的子控件列表里的控件,這是Qt提供的自動(dòng)內(nèi)存機(jī)制,而程序員可 能誤寫(xiě)刪除代碼,造成內(nèi)存泄露。
[0038] 除此之外還有其他屬于C++語(yǔ)言使用的中內(nèi)存泄露和冗余delete的情況,該方法 沒(méi)有涉及這些情況的檢測(cè)。
[0039] 本方法由幾個(gè)模塊組成,如圖1所示。
[0040] 在模塊1中,通過(guò)Windows系統(tǒng)提供的_findfirst()和_1^(111611:〇函數(shù)遍歷工程目 錄和子目錄下的所有.cpp和.h文件,把文件全路徑保存為string類(lèi)型,再存放到vector 類(lèi)型的cpp_file中。
[0041] 具體步驟是見(jiàn)附圖2:
[0042] 開(kāi)始,第一步,控制臺(tái)獲取工程目錄,第二步,判斷findfrist獲取當(dāng)前目錄下第一 個(gè)實(shí)例句柄,句柄值為-IL ?是,結(jié)束,否,第三步,,findnext根據(jù)_findfirst獲得的句柄遍歷 目錄下的所有實(shí)例,判斷返回值是否為〇 ?是,結(jié)束,否,進(jìn)入第四步,判斷此實(shí)例為子文件 夾嗎?是,當(dāng)前目錄鏈接文件夾名字得到新的目錄,返回第二步,否,進(jìn)入第五步,判斷此實(shí) 例為· cpp或· h文件嗎?是,將· cpp和· h文件的全名保存到vector類(lèi)型的cpp_file中, 返回第三步。
[0043] 在模塊2中,遍歷cppjile中的每個(gè)文件,按行讀取文件每行信息,解析new和 delete語(yǔ)句,得到Qt控件對(duì)象的創(chuàng)建信息和所有對(duì)象的刪除信息。
[0044] 解析文件中的new和delete語(yǔ)句時(shí),對(duì)于某一文件,用getLineO獲取文件中的 每一行代碼。
[0045] 解析過(guò)程見(jiàn)圖4,具體步驟是:
[0046] 開(kāi)始,第一步,判斷文件結(jié)束?是,結(jié)束,否,第二步,讀取每行文本,保存在string 類(lèi)型的line中,第三步,判斷l(xiāng)ine為注釋嗎?是,結(jié)束,否,進(jìn)入第四步,判斷是line為new 或delete語(yǔ)句?否,進(jìn)入第五步,判斷是new語(yǔ)句?是,解析line得到的刪除對(duì)象信息,文 件位置更信息,并將得到的信息保存在deleteOBJMap中,返回第一步;是new語(yǔ)句,進(jìn)入第 六步,解析語(yǔ)句獲得創(chuàng)建對(duì)象的類(lèi)別,第七步,根據(jù)類(lèi)別判斷為Qt空間類(lèi)?不是,結(jié)束,是, 第八步,將解析得到的Qt控件,父控件,文件位置信息保存到newOBJMap中,返回第一步。
[0047] 對(duì)于識(shí)別注釋部分和非注釋部分:
[0048] 注釋分兩種//行注釋?zhuān)?**/段注釋?zhuān)⑨尯痛a是要區(qū)別對(duì)待的,設(shè)置一個(gè)bool 變量result區(qū)別該行代碼是不是注釋即可。Result由解析代碼的函數(shù)返回值更新。
[0049] 若為行注釋?zhuān)苯犹^(guò)該行即可,并設(shè)result為commentEnd(表示注釋結(jié)束)。若 為段注釋?zhuān)覜](méi)有在一行中同時(shí)出現(xiàn)/*和*/,則result值為commentBegin (表示注釋開(kāi) 始)。若在一行中同時(shí)出現(xiàn)/*和*/,則result值為commentEnd(表示注釋結(jié)束)。
[0050] 解析每行代碼時(shí),根據(jù)result值選擇不同的解析函數(shù)parseCo_ent ()(解析注釋 的函數(shù)),parseCode ()(解析代碼的函數(shù))。
[0051] 對(duì)于識(shí)別QT控件對(duì)象分為兩步:
[0052] (1)識(shí)別出程序中創(chuàng)建對(duì)象的語(yǔ)句
[0053] 通過(guò)對(duì)Qt程序的了解,創(chuàng)建Qt控件對(duì)象一般是這種結(jié)構(gòu)。
[0054] 例如:
[0055] QPushButon m_button = new QPushButton(Parent);
[0056] 此行代碼最有標(biāo)志性的詞就是new和'=' 了,并且應(yīng)該是一個(gè)獨(dú)立的new這個(gè)關(guān) 鍵字,要排除***new***這種情況。
[0057] 首先,要從這行代碼中獲取的信息是:對(duì)象名(m_button),類(lèi)名(QPushButton), 父對(duì)象(parent)。
[0058] 思路是通過(guò)"=","new","來(lái)獲取每個(gè)標(biāo)識(shí)符的begin(第一個(gè)字符在整行 string中的索引),end (最后一個(gè)字符在整行string中的索引)。然后通過(guò)begin和end 即可獲得每個(gè)標(biāo)示符。
[0059] C++中string類(lèi)提供了很多接口可以直接使用。Substr (begin, Ien)用來(lái)截取子 串,find( "arg")用來(lái)尋找索引值,這兩個(gè)函數(shù)的配合使用可完成上述功能。
[0060] (2)判斷識(shí)別出的對(duì)象是不是Qt控件對(duì)象
[0061] 考慮到要識(shí)別所有的Qt控件對(duì)象,是一個(gè)繁雜的工作,所以只是找了一些常用的 Qt控件對(duì)象,以供識(shí)別。但是這不是固定的,如果有新的需要的話,可以在InheritTree. ini配置文件里手動(dòng)添加新的對(duì)象。
[0062] Qt控件所屬的類(lèi)都是有繼承關(guān)系的,且最終的父對(duì)象都為QWidget,針對(duì)這種繼 承樹(shù)的關(guān)系,建立了一個(gè)樹(shù)的結(jié)構(gòu),樹(shù)結(jié)構(gòu)的建立是通過(guò)讀取InheritTree. ini配置文件 建立的。
[0063] InheritTree. ini 文件結(jié)構(gòu)不例:
[0064] [樹(shù)的高度]
[0065] depthNum = η
[0066] [高度 0]
[0067] NodeNum = 1//當(dāng)前高度下結(jié)點(diǎn)數(shù)目
[0068] QWidget = NULL//等號(hào)左邊是空間類(lèi),右邊是起父類(lèi)
[0069] [高度 1]
[0070]
[0071] [高度 n-1]
[0072]
[0073] 樹(shù)結(jié)構(gòu)提供了 一個(gè)接口,findChild (std: : string key,,TreeNodePointer*p),入 口參數(shù)string key,返回值為T(mén)reeNodePointer*p,返回值是指針p指向樹(shù)中關(guān)鍵字為key 的結(jié)點(diǎn),如果樹(shù)中不存在關(guān)鍵字為key的結(jié)點(diǎn),則p的值為NULL。這個(gè)結(jié)構(gòu)能判斷樹(shù)中是 否存在關(guān)鍵字為key的結(jié)點(diǎn)。因此,把某個(gè)類(lèi)名作為實(shí)參傳給key,就可判斷此類(lèi)是不是Qt 的控件類(lèi)了,也就能判斷對(duì)象的對(duì)象是不是QT控件對(duì)象了。這里,TreeNodePointer為數(shù) 據(jù)結(jié)構(gòu)
[0074]
【權(quán)利要求】
1. 一種航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存使用的靜態(tài)檢查方法,其特征在于:在航管訓(xùn) 練系統(tǒng)中運(yùn)行一個(gè)QT程序內(nèi)存使用靜態(tài)的檢查程序,該程序運(yùn)行時(shí)將被檢查的代碼所在 的目錄作為運(yùn)行參數(shù),該目錄可以含有子目錄,得到檢測(cè)結(jié)果后,將監(jiān)測(cè)結(jié)果輸出到日志 文件或控制臺(tái); 本方法專(zhuān)門(mén)針對(duì)Qt程序中兩種Qt專(zhuān)屬的兩種內(nèi)存泄露情況提供檢查能力:Qt控件對(duì) 象沒(méi)有父控件,在堆中new了這個(gè)對(duì)象;Qt控件對(duì)象有父控件; 檢測(cè)在如下5個(gè)模塊中進(jìn)行: 1)、遍歷工程目錄和子目錄下的所有后綴名為.cpp和.h文件,把文件全路徑保存為 string類(lèi)型,再存放到vector類(lèi)型的cpp_file中; 2)、遍歷cpp_file中的每個(gè)文件,按行讀取文件每行信息,解析new和delete語(yǔ)句,得 到Qt控件對(duì)象的創(chuàng)建信息和所有對(duì)象的刪除信息; 3)、解析得到的Qt對(duì)象的創(chuàng)建信息存放在newOBJMap中,所有對(duì)象的刪除信息存放在 deIeteOBJMap中; 4)、遍歷newOBJMap中的每個(gè)元素,在deleteOBJMap中查找對(duì)應(yīng)的元素,如果存在對(duì)應(yīng) 元素,則將信息合并,存放在QtObjectMap中; 5)、遍歷QtObjectMap中每個(gè)元素,得到檢測(cè)結(jié)果,輸出到日志文件或控制臺(tái)。
2. 如權(quán)利要求1所述的航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存使用靜態(tài)檢查方法,其特征在 于:所述在1)模塊中進(jìn)行的檢測(cè),是通過(guò)Windows系統(tǒng)提供的_findfirst()和_findnext() 函數(shù)遍歷某個(gè)工程文件下的所有文件,并把.h和.cpp文件全路徑名存放在一個(gè)Vector類(lèi) 型cpp_file中,具體步驟是: 開(kāi)始,第一步,控制臺(tái)獲取工程目錄,第二步,判斷findfrist獲取當(dāng)前目錄下第一個(gè)實(shí) 例句柄,句柄值為-IL?是,結(jié)束,否,第三步,findnext根據(jù)_findfirst獲得的句柄遍歷目 錄下的所有實(shí)例,判斷返回值是否為〇 ?是,結(jié)束,否,進(jìn)入第四步,判斷此實(shí)例為子文件夾 嗎?是,當(dāng)前目錄鏈接文件夾名字得到新的目錄,返回第二步,否,進(jìn)入第五步,判斷此實(shí)例 為·cpp或·h文件嗎?是,第六步,將·cpp和·h文件的全名保存到vector類(lèi)型的cpp_file 中,返回第三步。
3. 如權(quán)利要求1所述的航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存使用靜態(tài)檢查方法,其特征在 于: 所述在模塊2)中進(jìn)行的檢測(cè)具體步驟是: 開(kāi)始,第一步,判斷文件結(jié)束?是,結(jié)束,否,第二步,讀取每行文本,保存在string類(lèi) 型的line中,第三步,判斷l(xiāng)ine為注釋嗎?是,結(jié)束,否,進(jìn)入第四步,判斷是line為new 或delete語(yǔ)句?否,進(jìn)入第五步,判斷是new語(yǔ)句?是,解析line得到的刪除對(duì)象信息,文 件位置更信息,并將得到的信息保存在deleteOBJMap中,返回第一步;是new語(yǔ)句,進(jìn)入第 六步,解析語(yǔ)句獲得創(chuàng)建對(duì)象的類(lèi)別,第七步,根據(jù)類(lèi)別判斷為Qt空間類(lèi)?不是,結(jié)束,是, 第八步,將解析得到的Qt控件,父控件,文件位置信息保存到newOBJMap中,返回第一步。
4. 如權(quán)利要求1所述的航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存使用靜態(tài)檢查方法,其特征在 于:所述在模塊4)中進(jìn)行的檢測(cè)具體步驟是: 開(kāi)始,第一步,判斷newOBJMap結(jié)束?是,結(jié)束,否,第二步,獲取newOBJMap的下一元 素,第三步,判斷在deleteOBJMap中找到對(duì)應(yīng)元素?是,第四步,將這兩個(gè)元素合并,保存 到QtObjectMap,結(jié)束;否,把newOBJMap信息保存到QtObjectMap中,無(wú)刪除信息補(bǔ)空,回 復(fù)到第一步。
5. 如權(quán)利要求3所述的航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存使用靜態(tài)檢查方法,其特征 在于:所述在模塊2)進(jìn)行的檢測(cè)具體步驟中第三步,判斷l(xiāng)ine是否為注釋識(shí)別對(duì)象分為兩 種://行注釋?zhuān)?**/段注釋?zhuān)⑨尯痛a區(qū)別對(duì)待,設(shè)置一個(gè)bool變量result區(qū)別該行代 碼是不是注釋即可,Result由解析代碼的函數(shù)返回值更新; 若為行注釋?zhuān)苯犹^(guò)該行即可,并設(shè)result為commentEnd,表示注釋結(jié)束;若為段注 釋?zhuān)覜](méi)有在一行中同時(shí)出現(xiàn)/*和*/,則result值為commentBegin,表示注釋開(kāi)始;若在 一行中同時(shí)出現(xiàn)/*和*/,則result值為commentEnd,表示注釋結(jié)束; 解析每行代碼時(shí),根據(jù)result值選擇不同的解析函數(shù),parseCo_ent()為解析注釋的 函數(shù),parseCodeO為解析代碼的函數(shù); 所述在模塊2)進(jìn)行的檢測(cè)具體步驟第七步中,根據(jù)類(lèi)別判斷為Qt空間類(lèi)識(shí)別對(duì)象時(shí) 分為兩步: (1) 識(shí)別出程序中創(chuàng)建對(duì)象的語(yǔ)句; (2) 判斷識(shí)別出的對(duì)象是不是Qt對(duì)象:Qt控件所屬的類(lèi)都是有繼承關(guān)系的,且最終的 父對(duì)象都為QWidget,針對(duì)這種繼承樹(shù)的關(guān)系,通過(guò)讀取InheritTree.ini配置文件建立一 個(gè)樹(shù)的結(jié)構(gòu),樹(shù)結(jié)構(gòu)提供了一個(gè)接口:findChiId,findChiId返回值為指針p指向樹(shù)中關(guān)鍵字 為key的結(jié)點(diǎn),如果樹(shù)中不存在關(guān)鍵字為key的結(jié)點(diǎn),則p的值為NULL,把某個(gè)類(lèi)名作為實(shí) 參傳給key,可判斷此類(lèi)是不是Qt的控件類(lèi)了,即能判斷對(duì)象的對(duì)象是不是Qt控件對(duì)象。
6. 如權(quán)利要求5所述的航管訓(xùn)練系統(tǒng)開(kāi)發(fā)中Qt程序內(nèi)存使用靜態(tài)檢查方法, 其特征在于:所述樹(shù)結(jié)構(gòu)提供的接口為findChild,入口參數(shù)stringkey,返回值為 TreeNodePointer*p,這里,TreeNodePointer為數(shù)據(jù)結(jié)構(gòu)
TreeNodePointer為指向一個(gè)描述樹(shù)形結(jié)構(gòu)節(jié)點(diǎn)的指針,該節(jié)點(diǎn)內(nèi)容包括:節(jié)點(diǎn)內(nèi)容key,該節(jié)點(diǎn)的子節(jié)點(diǎn)列表child_array,子節(jié)點(diǎn)個(gè)數(shù)child_num,節(jié)點(diǎn)的父節(jié)點(diǎn)parent。
【文檔編號(hào)】G06F11/36GK104461890SQ201410768041
【公開(kāi)日】2015年3月25日 申請(qǐng)日期:2014年12月12日 優(yōu)先權(quán)日:2014年12月12日
【發(fā)明者】胡術(shù), 王煜清, 唐麒麟 申請(qǐng)人:四川川大智勝軟件股份有限公司