




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、c語言編程技巧語言編程技巧之之 內(nèi)存管理-防止內(nèi)存 泄漏 1 7 內(nèi)存管理-防止內(nèi)存泄漏 w 7.1 內(nèi)存分配方式 w 7.2 malloc/free 的使用要點(diǎn) w 7.3 常見的內(nèi)存錯(cuò)誤及其對策 w 7.4 引用與指針的比較 w 7.5 指針與數(shù)組的對比 w 7.6 指針參數(shù)是如何傳遞內(nèi)存的 w 7.7 動態(tài)內(nèi)存自動釋放 w 7.8 杜絕“野指針” 2 7.1 內(nèi)存分配方式 w 內(nèi)存分配方式有三種: 從靜態(tài)存儲區(qū)域分配:內(nèi)存在程序編譯的時(shí) 候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn) 行期間都存在。例如全局變量,static變量。 在棧上創(chuàng)建 :在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變 量的存儲單元都可以在棧
2、上創(chuàng)建,函數(shù)執(zhí)行 結(jié)束時(shí)這些存儲單元自動被釋放。棧內(nèi)存分 配運(yùn)算內(nèi)置于處理器的指令集中,效率很高, 但是分配的內(nèi)存容量有限。 從堆上分配,亦稱動態(tài)內(nèi)存分配 malloc或new free或delete 3 7.2 malloc/free 的使用要點(diǎn) w malloc 語法:void * malloc(size_t size); 作用:申請一塊長度為length的整數(shù)類型的內(nèi)存 例子: 4 vnode *p; p = (vnode *) malloc (verticsnum * sizeof (vnode); int *p = (int *) malloc(sizeof(int) * lengt
3、h) 7.2 malloc/free 的使用要點(diǎn) w free 語法:void free( void * memblock ) 作用:釋放內(nèi)存 例子:free(p) 如果p是null指針,那么free對p無論操作多少次都不會 出問題 如果p不是null指針,那么free對p連續(xù)操作兩次就會導(dǎo) 致程序運(yùn)行錯(cuò)誤。 5 7.3 常見的內(nèi)存錯(cuò)誤及其對策 1)內(nèi)存分配未成功,卻使用了它 w 解決辦法:解決辦法:在使用內(nèi)存之前檢查指針是否為null。 如果指針p是函數(shù)的參數(shù),那么在函數(shù)的入口處用 assert(p!=null)進(jìn)行檢查。 如果是用malloc或new來申請內(nèi)存,應(yīng)該用 if(p=null)
4、 或 if(p!=null)進(jìn)行防錯(cuò)處理。 6 vnode *p; p = (vnode *) malloc (verticsnum * sizeof (vnode); p-firstarc = null; if (p = null) exit (overflow); /存儲分配失敗 7.3 常見的內(nèi)存錯(cuò)誤及其對策 2)內(nèi)存分配雖然成功,但是尚未初始化就引用它 w 解決辦法:解決辦法: 聲明后先初始化為0; 在真正使用指針之前,一定使其指向某個(gè)地址。 要么取某個(gè)變量的地址; 或者指向鏈表的頭節(jié)點(diǎn); 7 vnode *p; p-firstarc = 1; / 內(nèi)存訪問錯(cuò)誤,p未指向任何地方 7.
5、3 常見的內(nèi)存錯(cuò)誤及其對策 w 3)內(nèi)存分配成功并且已經(jīng)初始化,但操作越過了內(nèi) 存的邊界 w 解決辦法:解決辦法: 使用數(shù)組下標(biāo)(或者指針)時(shí)要判斷是否超過數(shù) 組長度 8 int location( sqlist l, elemtype p = l.elem; while ( k=l.length p+; if ( k= l.length) return k; else return 0; /location 7.3 常見的內(nèi)存錯(cuò)誤及其對策 w 4)忘記了釋放內(nèi)存,造成內(nèi)存泄露 w 造成造成問題:問題:含有這種錯(cuò)誤的函數(shù)每被調(diào)用一次就丟失 一塊內(nèi)存。過一段時(shí)間系統(tǒng)出現(xiàn)提示:內(nèi)存耗盡。 w 解決
6、辦法:解決辦法: malloc與free( new/delete )成對使用。 申請空間時(shí)就考慮什么時(shí)候釋放該空間申請空間時(shí)就考慮什么時(shí)候釋放該空間 釋放了內(nèi)存卻繼續(xù)使用它 7.3 常見的內(nèi)存錯(cuò)誤及其對策 w 5)釋放了內(nèi)存卻繼續(xù)使用它 有三種情況: (1)程序中的對象調(diào)用關(guān)系過于復(fù)雜,實(shí)在難以 搞清楚某個(gè)對象究竟是否已經(jīng)釋放了內(nèi)存,此時(shí) 應(yīng)該重新設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),從根本上解決對象管理 的混亂局面。 (2)函數(shù)的return語句寫錯(cuò)了,注意不要返回指向 “棧內(nèi)存”的“指針”或者“引用”,因?yàn)樵搩?nèi) 存在函數(shù)體結(jié)束時(shí)被自動銷毀。 (3)使用free或delete釋放了內(nèi)存后,沒有將指針 設(shè)置為null
7、。導(dǎo)致產(chǎn)生“野指針”。 10 7.3 常見的內(nèi)存錯(cuò)誤及其對策 w內(nèi)存管理的規(guī)則內(nèi)存管理的規(guī)則 用malloc之后,應(yīng)該立即檢查指針值是否為null。 防止使用指針值為null的內(nèi)存。 不要忘記為數(shù)組和動態(tài)內(nèi)存賦初值。防止將未被 初始化的內(nèi)存作為右值使用。 避免數(shù)組或指針的下標(biāo)越界,特別要當(dāng)心發(fā)生 “多1”或者“少1”操作。 動態(tài)內(nèi)存的申請與釋放必須配對,防止內(nèi)存泄漏。 用free釋放了內(nèi)存之后,立即將指針設(shè)置為null, 防止產(chǎn)生“野指針”。 11 7.4 引用與指針的比較 w 表示符差別表示符差別 引用引用 printf( “x= %dn”,x); int n = 0; func1(n);
8、printf( “n= %dn”,n); 7.4 引用與指針的比較引用與指針的比較 w 函數(shù)的參數(shù)和返回值的傳遞方式函數(shù)的參數(shù)和返回值的傳遞方式 值傳遞值傳遞 :例例: 輸出結(jié)果:輸出結(jié)果: x = 10 x = 10 n n = = 0 0 13 void func2(int *x) (* x) = (* x) + 10; printf( “x= %dn”,x); int n = 0; func1( printf( “n = %dn”,n); 7.4 引用與指針的比較 w 函數(shù)的參數(shù)和返回值的傳遞方式 指針傳遞 輸出結(jié)果: x = 10 n = 10 14 void func3(int pr
9、intf( “x= %dn”,x); int n = 0; func3(n); printf( “n = %dn”,n); 7.4 引用與指針的比較 w 函數(shù)的參數(shù)和返回值的傳遞方式 引用傳遞 輸出結(jié)果: x = 10 n = 10 15 7.5 指針與數(shù)組的對比 w 差別差別 數(shù)組數(shù)組: 要么在靜態(tài)存儲區(qū)被創(chuàng)建(如全局?jǐn)?shù)組),要么在棧上要么在靜態(tài)存儲區(qū)被創(chuàng)建(如全局?jǐn)?shù)組),要么在棧上 被創(chuàng)建被創(chuàng)建 數(shù)組名對應(yīng)著(而不是指向)一塊內(nèi)存數(shù)組名對應(yīng)著(而不是指向)一塊內(nèi)存 其地址與容量在生命期內(nèi)保持不變其地址與容量在生命期內(nèi)保持不變 只有數(shù)組的內(nèi)容可以改變只有數(shù)組的內(nèi)容可以改變 指針指針: 隨時(shí)指
10、向任意類型的內(nèi)存塊隨時(shí)指向任意類型的內(nèi)存塊 動態(tài)生存動態(tài)生存 在數(shù)據(jù)堆在數(shù)據(jù)堆 16 7.5 指針與數(shù)組的對比 w 差別 內(nèi)存的容量大小 char a = hello world; char *p = a; sizeof(a) ?/ 12字節(jié) sizeof(p) ?/ 4字節(jié) void func(char a100) sizeof(a) ? / 4字節(jié)而不是100字節(jié) 17 7.5 指針與數(shù)組的對比 w 動態(tài)內(nèi)存會不會自動釋放? 例: w 指針應(yīng)該注意的特性 指針消亡了,并不表示它所指的內(nèi)存會被自動釋 放。 內(nèi)存被釋放了,并不表示指針會消亡或者成了 null指針。 void func(void
11、) / 動態(tài)內(nèi)存會自動釋放嗎? char *p = (char *) malloc(100); 18 7.6 指針參數(shù)是如何傳遞內(nèi)存的 *如果函數(shù)的參數(shù)是一個(gè)指針,不要指望用該指針去申請動態(tài)內(nèi)存 void getmemory(char *p, int num) p = (char *)malloc(sizeof(char) * num); void test(void) char *str = null; getmemory(str, 100); / str 仍然為 null strcpy(str, hello);/ 運(yùn)行錯(cuò)誤 19 7.6 指針參數(shù)是如何傳遞內(nèi)存的 *如果函數(shù)的參數(shù)是一個(gè)指針
12、,不要指望用該指針去申請動態(tài)內(nèi)存 void getmemory2(char *p, int num) *p = (char *)malloc(sizeof(char) * num); void test(void) char *str = null; getmemory( / str 就不是就不是 null,而指向一個(gè),而指向一個(gè)100字符的空間字符的空間 strcpy(str, “hello”);/ 正確正確 20 7.6 指針參數(shù)是如何傳遞內(nèi)存的 * 不要用return語句返回指向“棧內(nèi)存”的指針 char *getstring(void) char p = hello world; re
13、turn p; / 編譯器將提出警告編譯器將提出警告 void test4(void) char *str = null; str = getstring(); / str 的內(nèi)容是垃圾的內(nèi)容是垃圾 printf(“%sn”,str ); 21 7.6 指針參數(shù)是如何傳遞內(nèi)存的 * 不要用return語句返回指向“棧內(nèi)存”的指針 char *getstring(void) char *p = hello world; return p; / 編譯器將提出警告編譯器將提出警告 void test4(void) char *str = null; str = getstring(); / str 的內(nèi)容是垃圾的內(nèi)容是垃圾 printf(“%sn”,str ); 如果換 成常量 該如何? 22 7.7 動態(tài)內(nèi)存自動釋放 w free函數(shù)特點(diǎn) 釋放指針?biāo)傅膬?nèi)存 沒有銷毀指針,故指針地址仍然不變(非null) 例: char *p = (char *) malloc(100); strcpy(p, “hello”); free(p); / p 所指的內(nèi)存被釋放,但是所指的內(nèi)存被釋放,但是p所指的地址仍然不變所指的地址仍然不變 if(p != null)
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年醫(yī)用消毒滅菌設(shè)備項(xiàng)目合作計(jì)劃書
- 科技與可持續(xù)性綠色建筑設(shè)計(jì)的未來路徑
- 合同范本專項(xiàng)條款
- 科技職場溝通禮儀與實(shí)踐
- 公眾號廣告推廣合同范本
- 口腔會議合同范本
- 合同范本與合同區(qū)別
- 雙方購房轉(zhuǎn)讓合同范本
- 內(nèi)墻涂料仿瓷施工合同范本
- 叉車腳輪銷售合同范例
- 中建吊籃安拆專項(xiàng)施工方案(專家論證版)
- 《汽車維修接待實(shí)務(wù)》 課件全套 孫麗學(xué)習(xí)情景1-8 汽車維修服務(wù)接待認(rèn)知 -新能源汽車維修接待
- 2020年礦建監(jiān)理工作總結(jié)
- 獸醫(yī)學(xué)英語詞匯【參考】
- 浙江省溫州市2024-2025學(xué)年高三上學(xué)期一模英語試題 含解析
- 建筑施工安全生產(chǎn)包保責(zé)任實(shí)施方案
- 《時(shí)代與變革?版畫藝術(shù)的魅力》教學(xué)設(shè)計(jì)
- 《民法典》醫(yī)療損害責(zé)任篇培訓(xùn)課件
- 咨詢公司項(xiàng)目風(fēng)險(xiǎn)控制方案
- 2024年初一英語閱讀理解專項(xiàng)練習(xí)及答案
- 病例報(bào)告表(CRF)模板
評論
0/150
提交評論