版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、C語言中的指針和內(nèi)存泄漏在使用 C 語言時(shí),您是否對(duì)花時(shí)間調(diào)試指針和內(nèi)存泄漏問題感到厭倦?如果是這樣,那么本文就適合您。您將了解可能導(dǎo)致內(nèi)存破壞的指針操作類型,您還將研究一些場景,了解要在使用動(dòng)態(tài)內(nèi)存分配時(shí)考慮什么問題。引言對(duì)于任何使用 C 語言的人,如果問他們 C 語言的最大煩惱是什么,其中許多人可能會(huì)回答說是指針和內(nèi)存泄漏。這些的確是消耗了開發(fā)人員大多數(shù)調(diào)試時(shí)間的事項(xiàng)。指針和內(nèi)存泄漏對(duì)某些開發(fā)人員來說似乎令人畏懼,但是一旦您了解了指針及其關(guān)聯(lián)內(nèi)存操作的基礎(chǔ),它們就是您在 C 語言中擁有的最強(qiáng)大工具。本文將與您分享開發(fā)人員在開始使用指針來編程前應(yīng)該知道的秘密。本文內(nèi)容包括:導(dǎo)致內(nèi)存破壞的指針
2、操作類型在使用動(dòng)態(tài)內(nèi)存分配時(shí)必須考慮的檢查點(diǎn)導(dǎo)致內(nèi)存泄漏的場景如果您預(yù)先知道什么地方可能出錯(cuò),那么您就能夠小心避免陷阱,并消除大多數(shù)與指針和內(nèi)存相關(guān)的問題。 什么地方可能出錯(cuò)?有幾種問題場景可能會(huì)出現(xiàn),從而可能在完成生成后導(dǎo)致問題。在處理指針時(shí),您可以使用本文中的信息來避免許多問題。未初始化的內(nèi)存在本例中,p 已被分配了 10 個(gè)字節(jié)。這 10 個(gè)字節(jié)可能包含垃圾數(shù)據(jù),如圖 1 所示。char *p = malloc ( 10 ;圖 1. 垃圾數(shù)據(jù)如果在對(duì)這個(gè) p 賦值前,某個(gè)代碼段嘗試訪問它,則可能會(huì)獲得垃圾值,您的程序可能具有不可預(yù)測的行為。p 可能具有您的程序從未曾預(yù)料到的值。良好的實(shí)踐
3、是始終結(jié)合使用 memset 和 malloc,或者使用 calloc。char *p = malloc (10;memset(p,0,10;現(xiàn)在,即使同一個(gè)代碼段嘗試在對(duì) p 賦值前訪問它,該代碼段也能正確處理 Null 值(在理想情況下應(yīng)具有的值),然后將具有正確的行為。內(nèi)存覆蓋由于 p 已被分配了 10 個(gè)字節(jié),如果某個(gè)代碼片段嘗試向 p 寫入一個(gè) 11 字節(jié)的值,則該操作將在不告訴您的情況下自動(dòng)從其他某個(gè)位置“吃掉”一個(gè)字節(jié)。讓我們假設(shè)指針 q 表示該內(nèi)存。圖 2. 原始 q 內(nèi)容圖 3. 覆蓋后的 q 內(nèi)容結(jié)果,指針 q 將具有從未預(yù)料到的內(nèi)容。即使您的模塊編碼得足夠好,也可能由于某
4、個(gè)共存模塊執(zhí)行某些內(nèi)存操作而具有不正確的行為。下面的示例代碼片段也可以說明這種場景。char *name = (char * malloc(11; / Assign some value to namememcpy ( p,name,11; / Problem begins here在本例中,memcpy 操作嘗試將 11 個(gè)字節(jié)寫到 p,而后者僅被分配了 10 個(gè)字節(jié)。作為良好的實(shí)踐,每當(dāng)向指針寫入值時(shí),都要確保對(duì)可用字節(jié)數(shù)和所寫入的字節(jié)數(shù)進(jìn)行交叉核對(duì)。一般情況下,memcpy 函數(shù)將是用于此目的的檢查點(diǎn)。內(nèi)存讀取越界內(nèi)存讀取越界 (overread 是指所讀取的字節(jié)數(shù)多于它們應(yīng)有的字節(jié)數(shù)。
5、這個(gè)問題并不太嚴(yán)重,在此就不再詳述了。下面的代碼提供了一個(gè)示例。char *ptr = (char *malloc(10;char name20 ;memcpy ( name,ptr,20; / Problem begins here在本例中,memcpy 操作嘗試從 ptr 讀取 20 個(gè)字節(jié),但是后者僅被分配了 10 個(gè)字節(jié)。這還會(huì)導(dǎo)致不希望的輸出。內(nèi)存泄漏內(nèi)存泄漏可能真正令人討厭。下面的列表描述了一些導(dǎo)致內(nèi)存泄漏的場景。重新賦值 我將使用一個(gè)示例來說明重新賦值問題。char *memoryArea = malloc(10;char *newArea = malloc(10;這向如下面的圖
6、 4 所示的內(nèi)存位置賦值。圖 4. 內(nèi)存位置memoryArea 和 newArea 分別被分配了 10 個(gè)字節(jié),它們各自的內(nèi)容如圖 4 所示。如果某人執(zhí)行如下所示的語句(指針重新賦值)memoryArea = newArea; 則它肯定會(huì)在該模塊開發(fā)的后續(xù)階段給您帶來麻煩。 在上面的代碼語句中,開發(fā)人員將 memoryArea 指針賦值給 newArea 指針。結(jié)果,memoryArea 以前所指向的內(nèi)存位置變成了孤立的,如下面的圖 5 所示。它無法釋放,因?yàn)闆]有指向該位置的引用。這會(huì)導(dǎo)致 10 個(gè)字節(jié)的內(nèi)存泄漏。圖 5. 內(nèi)存泄漏在對(duì)指針賦值前,請(qǐng)確保內(nèi)存位置不會(huì)變?yōu)楣铝⒌?。首先釋放父塊
7、假設(shè)有一個(gè)指針 memoryArea,它指向一個(gè) 10 字節(jié)的內(nèi)存位置。該內(nèi)存位置的第三個(gè)字節(jié)又指向某個(gè)動(dòng)態(tài)分配的 10 字節(jié)的內(nèi)存位置,如圖 6 所示。圖 6. 動(dòng)態(tài)分配的內(nèi)存free(memoryArea如果通過調(diào)用 free 來釋放了 memoryArea,則 newArea 指針也會(huì)因此而變得無效。newArea 以前所指向的內(nèi)存位置無法釋放,因?yàn)橐呀?jīng)沒有指向該位置的指針。換句話說,newArea 所指向的內(nèi)存位置變?yōu)榱斯铝⒌?,從而?dǎo)致了內(nèi)存泄漏。每當(dāng)釋放結(jié)構(gòu)化的元素,而該元素又包含指向動(dòng)態(tài)分配的內(nèi)存位置的指針時(shí),應(yīng)首先遍歷子內(nèi)存位置(在此例中為 newArea),并從那里開始釋放,然
8、后再遍歷回父節(jié)點(diǎn)。這里的正確實(shí)現(xiàn)應(yīng)該為:free( memoryArea->newArea;free(memoryArea;返回值的不正確處理 有時(shí),某些函數(shù)會(huì)返回對(duì)動(dòng)態(tài)分配的內(nèi)存的引用。跟蹤該內(nèi)存位置并正確地處理它就成為了 calling 函數(shù)的職責(zé)。char *func ( return malloc(20; / make sure to memset this location to 0void callingFunc ( func ( ; / Problem lies here在上面的示例中,callingFunc( 函數(shù)中對(duì) func( 函數(shù)的調(diào)用未處理該內(nèi)存位置的返回地址。結(jié)
9、果,func( 函數(shù)所分配的 20 個(gè)字節(jié)的塊就丟失了,并導(dǎo)致了內(nèi)存泄漏。歸還您所獲得的在開發(fā)組件時(shí),可能存在大量的動(dòng)態(tài)內(nèi)存分配。您可能會(huì)忘了跟蹤所有指針(指向這些內(nèi)存位置),并且某些內(nèi)存段沒有釋放,還保持分配給該程序。始終要跟蹤所有內(nèi)存分配,并在任何適當(dāng)?shù)臅r(shí)候釋放它們。事實(shí)上,可以開發(fā)某種機(jī)制來跟蹤這些分配,比如在鏈表節(jié)點(diǎn)本身中保留一個(gè)計(jì)數(shù)器(但您還必須考慮該機(jī)制的額外開銷)。訪問空指針訪問空指針是非常危險(xiǎn)的,因?yàn)樗赡苁鼓某绦虮罎?。始終要確保您不是 在訪問空指針。總結(jié)本文討論了幾種在使用動(dòng)態(tài)內(nèi)存分配時(shí)可以避免的陷阱。要避免內(nèi)存相關(guān)的問題,良好的實(shí)踐是:始終結(jié)合使用 memset 和 malloc,或始終使用 calloc。每當(dāng)向指針寫入值時(shí),都要確保對(duì)可用字節(jié)數(shù)和所寫入的字節(jié)數(shù)進(jìn)行交叉核對(duì)。在對(duì)指針
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2施工工藝控制標(biāo)準(zhǔn)圖示-電儀篇
- 財(cái)務(wù)會(huì)計(jì)知識(shí)點(diǎn)
- 石河子大學(xué)《體能訓(xùn)練理論與方法》2022-2023學(xué)年第一學(xué)期期末試卷
- 石河子大學(xué)《平面設(shè)計(jì)基礎(chǔ)》2022-2023學(xué)年第一學(xué)期期末試卷
- 石河子大學(xué)《教育研究方法》2022-2023學(xué)年第一學(xué)期期末試卷
- 沈陽理工大學(xué)《體育》2022-2023學(xué)年第一學(xué)期期末試卷
- 沈陽理工大學(xué)《機(jī)械制造技術(shù)基礎(chǔ)》2021-2022學(xué)年第一學(xué)期期末試卷
- 沈陽理工大學(xué)《高級(jí)人工智能》2021-2022學(xué)年期末試卷
- 關(guān)于向政府請(qǐng)示履行合同的請(qǐng)示書
- 國外銷售藥品合同
- 2024年中考語文復(fù)習(xí)分類必刷:非連續(xù)性文本閱讀(含答案解析)
- 項(xiàng)目經(jīng)理或管理招聘面試題與參考回答(某大型國企)
- 2024年國際貿(mào)易實(shí)務(wù)試題及答案
- 冀少版(2024)七年級(jí)上冊(cè)生物單元+期中+期末共6套學(xué)情評(píng)估測試卷匯編(含答案)
- 2024年四川宜賓江安縣考調(diào)事業(yè)單位工作人員7人歷年(高頻重點(diǎn)復(fù)習(xí)提升訓(xùn)練)共500題附帶答案詳解
- 2025高考數(shù)學(xué)一輪復(fù)習(xí)-4.1-任意角和弧度制及三角函數(shù)的概念【課件】
- 工程進(jìn)度款申請(qǐng)表
- 當(dāng)代社會(huì)政策分析 課件 第八章 兒童社會(huì)政策
- 2023年徽商銀行市區(qū)支行招聘綜合柜員信息筆試上岸歷年典型考題與考點(diǎn)剖析附帶答案詳解
- 2024年湖南化工職業(yè)技術(shù)學(xué)院單招職業(yè)技能測試題庫帶答案解析
- JGT 472-2015 鋼纖維混凝土
評(píng)論
0/150
提交評(píng)論