版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
C++內(nèi)存管理詳解程序員們經(jīng)常編寫內(nèi)存管理程序,往往提心吊膽。如果不想觸雷,唯一的解決辦法就是發(fā)現(xiàn)所有潛伏的地雷并且排除它們,躲是躲不了的。本文的內(nèi)容比一般教科書的要深入得多,讀者需細(xì)心閱讀,做到真正地通曉內(nèi)存管理。1、內(nèi)存分配方式內(nèi)存分配方式有三種:(1)從靜態(tài)存儲(chǔ)區(qū)域分配。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。例如全局變量,static變量。(2)在棧上創(chuàng)建。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。棧內(nèi)存分配運(yùn)算內(nèi)置于處理器的指令集中,效率很高,但是分配的內(nèi)存容量有限。(3)從堆上分配,亦稱動(dòng)態(tài)內(nèi)存分配。程序在運(yùn)行的時(shí)候用malloc或new申請任意多少的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free或delete釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由我們決定,使用非常靈活,但問題也最多。2、常見的內(nèi)存錯(cuò)誤及其對策發(fā)生內(nèi)存錯(cuò)誤是件非常麻煩的事情。編譯器不能自動(dòng)發(fā)現(xiàn)這些錯(cuò)誤,通常是在程序運(yùn)行時(shí)才能捕捉到。而這些錯(cuò)誤大多沒有明顯的癥狀,時(shí)隱時(shí)現(xiàn),增加了改錯(cuò)的難度。有時(shí)用戶怒氣沖沖地把你找來,程序卻沒有發(fā)生任何問題,你一走,錯(cuò)誤又發(fā)作了。常見的內(nèi)存錯(cuò)誤及其對策如下:*內(nèi)存分配未成功,卻使用了它。編程新手常犯這種錯(cuò)誤,因?yàn)樗麄儧]有意識(shí)到內(nèi)存分配會(huì)不成功。常用解決辦法是,在使用內(nèi)存之前檢查指針是否為NULL。如果指針p是函數(shù)的參數(shù),那么在函數(shù)的入口處用assert(p!=NULL)進(jìn)行檢查。如果是用malloc或new來申請內(nèi)存,應(yīng)該用if(p==NULL)或if(p!=NULL)進(jìn)行防錯(cuò)處理。*內(nèi)存分配雖然成功,但是尚未初始化就引用它。犯這種錯(cuò)誤主要有兩個(gè)起因:一是沒有初始化的觀念;二是誤以為內(nèi)存的缺省初值全為零,導(dǎo)致引用初值錯(cuò)誤(例如數(shù)組)。內(nèi)存的缺省初值究竟是什么并沒有統(tǒng)一的標(biāo)準(zhǔn),盡管有些時(shí)候?yàn)榱阒担覀儗幙尚牌錈o不可信其有。所以無論用何種方式創(chuàng)建數(shù)組,都別忘了賦初值,即便是賦零值也不可省略,不要嫌麻煩。*內(nèi)存分配成功并且已經(jīng)初始化,但操作越過了內(nèi)存的邊界。例如在使用數(shù)組時(shí)經(jīng)常發(fā)生下標(biāo)“多1”或者“少1”的操作。特別是在for循環(huán)語句中,循環(huán)次數(shù)很容易搞錯(cuò),導(dǎo)致數(shù)組操作越界。*忘記了釋放內(nèi)存,造成內(nèi)存泄露。含有這種錯(cuò)誤的函數(shù)每被調(diào)用一次就丟失一塊內(nèi)存。剛開始時(shí)系統(tǒng)的內(nèi)存充足,你看不到錯(cuò)誤。終有一次程序突然死掉,系統(tǒng)出現(xiàn)提示:內(nèi)存耗盡。動(dòng)態(tài)內(nèi)存的申請與釋放必須配對,程序中malloc與free的使用次數(shù)一定要相同,否則肯定有錯(cuò)誤(new/delete同理)。*釋放了內(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ù)的盾retur須n崇語句寫錯(cuò)了受,注意不要烘返回指向柏“暫棧內(nèi)存必”窄的監(jiān)“地指針億”僵或者爬“觸引用味”米,因?yàn)樵搩?nèi)松存在函數(shù)體軟結(jié)束時(shí)被自身動(dòng)銷毀。芬(屋3嗽)使用絞free為或侮delet耀e扯釋放了內(nèi)存尤后,沒有將阻指針設(shè)置為守NULL投。導(dǎo)致產(chǎn)生朽“國野指針銳”田。僻【規(guī)則幟1射】用忌mallo甚c壤或負(fù)new球申請內(nèi)存之龜后,應(yīng)該立未即檢查指針滑值是否為櫻NULL廊。防止使用單指針值為貪NULL嗚的內(nèi)存。野【規(guī)則攪2優(yōu)】不要忘記斑為數(shù)組和動(dòng)蠢態(tài)內(nèi)存賦初質(zhì)值。防止將告未被初始化賣的內(nèi)存作為壟右值使用。員【規(guī)則計(jì)3米】避免數(shù)組菠或指針的下刑標(biāo)越界,特釘別要當(dāng)心發(fā)哪生渴“臉多數(shù)1”盜或者犧“襪少貪1”樂操作。臉【規(guī)則塘4訪】動(dòng)態(tài)內(nèi)存今的申請與釋薦放必須配對叼,防止內(nèi)存淋泄漏。騾【規(guī)則窄5育】用巷free搬或歷delet胳e把釋放了內(nèi)存鋼之后,立即芳將指針設(shè)置危為祥NULL墳,防止產(chǎn)生累“洲野指針餓”套。筍3鄰、指針與數(shù)庫組的對比加環(huán)C++/C暮程序中,指衰針和數(shù)組在與不少地方可汽以相互替換價(jià)著用,讓人肚產(chǎn)生一種錯(cuò)呆覺,以為兩物者是等價(jià)的街。媽數(shù)組要偉么在靜態(tài)存刊儲(chǔ)區(qū)被創(chuàng)建糧(如全局?jǐn)?shù)趨組),要么亂在棧上被創(chuàng)賓建。數(shù)組名辦對應(yīng)著(而能不是指向)廳一塊內(nèi)存,布其地址與容互量在生命期敞內(nèi)保持不變稈,只有數(shù)組緣的內(nèi)容可以莫改變。恒指針可容以隨時(shí)指向竭任意類型的誘內(nèi)存塊,它役的特征是周“塊可變纏”堅(jiān),所以我們舞常用指針來提操作動(dòng)態(tài)內(nèi)盆存。指針遠(yuǎn)弦比數(shù)組靈活碼,但也更危蛙險(xiǎn)。交下面以風(fēng)字符串為例遼比較指針與旨數(shù)組的特性環(huán)。牧悄3.1貼修改內(nèi)容悼示例啊3-1撒中,字符數(shù)糾組拘a賽的容量是決6抓個(gè)字符,其浮內(nèi)容為表hello未。稈a歷的內(nèi)容可以訪改變,如盞a[0]=口‘X’躬。指針焰p稀指向常量字槐符串?!俺痺orld欲”代(位于靜態(tài)云存儲(chǔ)區(qū),內(nèi)起容為夜world趨),常量字圖符串的內(nèi)容魯是不可以被噸修改的。從枯語法上看,編編譯器并不憲覺得語句孔p[0]長=‘X’徒有什么不妥奇,但是該語沙句企圖修改笛常量字符串自的內(nèi)容而導(dǎo)夏致運(yùn)行錯(cuò)誤憤。贊char貞a[]=符“hel膨lo”;亡a[0]椒=‘X’轎;譜cout鞏<<a盲<<en獸dl;雖char短*p=旅“栽world歪”氧;//浪注意p指向態(tài)常量字符串銳p[0]怎=‘X’牢;//巡編譯器不能叼發(fā)現(xiàn)該錯(cuò)誤萬cout弄<<p非<<en暈dl;耗瞎示例違3.1啊修改數(shù)組和榨指針的內(nèi)容速母蛾騾3.2醬內(nèi)容復(fù)制與演比較撿不能對陡數(shù)組名進(jìn)行葡直接復(fù)制與敘比較。示例暴7-3-2零中,若想把薯數(shù)組侮a巨的內(nèi)容復(fù)制扣給數(shù)組嚇b縫,不能用語郵句標(biāo)b=樣a吸,否則將產(chǎn)爺生編譯錯(cuò)誤饅。應(yīng)該用標(biāo)狐準(zhǔn)庫函數(shù)雖strcp急y碑進(jìn)行復(fù)制。顯同理,比較值b銜和標(biāo)a群的內(nèi)容是否忌相同,不能先用心if(b=吧=a)烏來判斷,應(yīng)菊該用標(biāo)準(zhǔn)庫淚函數(shù)倘strcm已p嚴(yán)進(jìn)行比較。爬語句詢p=a躍叼并不能把捆a礙的內(nèi)容復(fù)制質(zhì)指針帽p觸,而是把宋a蠅的地址賦給割了折p鬼。要想復(fù)制水a(chǎn)范的內(nèi)容,可浪以先用庫函廳數(shù)臣mallo嫁c棕為件p伙申請一塊容練量為葉strle聰n(a)+撤1險(xiǎn)個(gè)字符的內(nèi)怖存,再用孤strcp稠y再進(jìn)行字符串擇復(fù)制。同理廟,語句零if(p=貝=a)罪比較的不是刊內(nèi)容而是地監(jiān)址,應(yīng)該用擊庫函數(shù)亡strcm驗(yàn)p臭來比較。拜//齊數(shù)組知char蠢a[]=誘"hel沿lo";鹽char精b[10]讓;廉strcp歪y(b,潑a);/寺/不能用票b=怠a;口if(st現(xiàn)rcmp(柔b,a)石==0吊)//驟不能用i焦f(b狠==a)丸//建指針任intl絹en=工strle饅n(a);肚char璃*線p=(罩char幅*)mal此loc(s家izeof復(fù)(char假)*(le期n+1))桂;罩strcp劃y(p,a仗);//刪不要用植p=a漸;斜if(st爆rcmp(佩p,a)電爭==0)乘//不派要用if烈(p=戒=a)至撤示例舉3.2嬌數(shù)組和指針椅的內(nèi)容復(fù)制撥與比較茄郊常3.3閉計(jì)算內(nèi)存容穩(wěn)量皆用運(yùn)算雙符也sizeo消f怖可以計(jì)算出尚數(shù)組的容量鬼(字節(jié)數(shù))士。墻示例化7-3-3陸(戚a撕)中,棵sizeo制f(a)項(xiàng)的值是禿12域(注意別忘嘉了奇’’渡)。指針貪p鵝指向握a豆,但是圍size珍of(p)裕的值卻是依4糖。這是因?yàn)榇餾izeo劃f(p)塵得到的是一脅個(gè)指針變量肆的字節(jié)數(shù),紙相當(dāng)于頁sizeo帳f(cha沉r*)慘,而不是壞p沫所指的內(nèi)存項(xiàng)容量。虹C++/趕C獲語言沒有辦闊法知道指針仍所指的內(nèi)存拉容量,除非明在申請內(nèi)存維時(shí)記住它。賽插注意當(dāng)數(shù)組拘作為函數(shù)的統(tǒng)參數(shù)進(jìn)行傳擔(dān)遞時(shí),該數(shù)侄組自動(dòng)退化則為同類型的殿指針。雀示例匯7-3-3梨(沾b斬)中,不論瘋數(shù)組愚a床的容量是多擱少,裝sizeo菜f(a)喇始終等于女sizeo倍f(cha堵r調(diào)*)。榨char梁a[]=屠"hel株lowo溫rld";田char畫*p=側(cè)a;本cout<摟<siz慌eof(a指)<<挑endl;扔//1撒2梳字節(jié)嚼cout<缺<siz窩eof(p雷)<<起endl;憶//4諒字節(jié)喊奮示例桂3.3鉆(哪a激)椅場計(jì)算數(shù)組和膠指針的內(nèi)存充容量名鉆鏟void尚Func(晴char商a[100猛])育{母cout頂<<si潤zeof(鋪a)<<急endl漿;//織4攜字節(jié)而不是版100食字節(jié)尚}巖沖示例辭3.3柏(啞b怒)這伙數(shù)組退化為宴指針床4值、指針參數(shù)聯(lián)是如何傳遞詢內(nèi)存的?皇鞋感如果函數(shù)的儉參數(shù)是一個(gè)省指針,不要來指望用該指擁針去申請動(dòng)朋態(tài)內(nèi)存。示綿例填7-4-1厲中,畝Test辯函數(shù)的語句射GetMe窮mory(鉗str,濕200)偏并沒有使瞎str封獲得期望的襪內(nèi)存,倆str題依舊是厚NULL粉,為什么烘?胞void計(jì)GetMe只mory(西char慘*p,i瞞ntnu饅m)閥{笛p=繭(char殘*)ma套lloc(積sizeo浩f(cha粘r)*肆num);維}戲void鋼Test(妹void)裹{亮char胳*str經(jīng)=NU膀LL;歷趕GetMe啦mory(熊str,攻100);育//s茂tr儀仍然為田NULL觸勸strcp否y(str養(yǎng),"he火llo")驕;//瞇運(yùn)行錯(cuò)誤撇}軌蠟示例片4.1繩試圖用指針懼參數(shù)申請動(dòng)美態(tài)內(nèi)存光徑竟毛病出在函執(zhí)數(shù)跟GetMe淚mory暫中。編譯器萬總是要為函粗?jǐn)?shù)的每個(gè)參恭數(shù)制作臨時(shí)室副本,指針王參數(shù)媽p貸的副本是罷_p倉,編譯器使倆_p=桶p稱。如果函數(shù)偷體內(nèi)的程序私修改了岡_p挺的內(nèi)容,就構(gòu)導(dǎo)致參數(shù)請p圍的內(nèi)容作相壤應(yīng)的修改。萬這就是指針黨可以用作輸團(tuán)出參數(shù)的原慶因。在本例鄰中,廊_p救申請了新的稈內(nèi)存,只是濾把鑼_p海所指的內(nèi)存客地址改變了乎,但是優(yōu)p蓄絲毫未變??兯院瘮?shù)觸GetMe爽mory改并不能輸出汗任何東西。役事實(shí)上,每困執(zhí)行一次扎GetMe植mory閑就會(huì)泄露一川塊內(nèi)存,因都為沒有用叔free踐釋放內(nèi)存。糾如果非腫得要用指針頸參數(shù)去申請?zhí)巸?nèi)存,那么埋應(yīng)該改用捷“廳指向指針的渴指針芳”食,見示例夕4.2亞。休void架GetMe叼mory2謹(jǐn)(char毅**p,尤int鼻num)到{炊*p=弓(cha權(quán)r*)m產(chǎn)alloc采(size伶of(ch花ar)*岸num)射;禁}礎(chǔ)void歇Test2罪(void啊)鐵{玉char哨*str覺=NU稈LL;配GetM攻emory烈2(淚&str,眠100)猜;//銀注意參數(shù)是段&暖str,而評不是str濕strc傳py(st嫂r,"h咽ello"城);恩cout欲<<st革r<<詠endl;疼free蜜(str)肚;吳}限高示例穴4.2粗用指向指針竄的指針申請涂動(dòng)態(tài)內(nèi)存姓畫宰碗由于安“狗指向指針的覽指針誦”苦這個(gè)概念不更容易理解,益我們可以用辣函數(shù)返回值撫來傳遞動(dòng)態(tài)初內(nèi)存。這種秀方法更加簡鉗單,見示例絡(luò)4.3霸。雨char帥*GetM廈emory科3(int脖num)芒{父char祖*p=主(cha曬r*)m居alloc請(size雜of(ch漁ar)剩*nu姨m);擊retu沿rnp;勸}姜void杜Test3叉(void件)畜{慌char見*str砍=跌NULL賺;璃str肉=Get營Memor展y3(10攪0);拐strc殖py(st炎r,"h漠ello"渠);肅cout灶<<st黃r<<祖endl;枝free殖(str)皺;兄}槐寇示例掙4.3勾用函數(shù)返回磨值來傳遞動(dòng)戚態(tài)內(nèi)存哲極過用函數(shù)返回警值來傳遞動(dòng)此態(tài)內(nèi)存這種界方法雖然好蘆用,但是常鞏常有人把奧retur摧n謀語句用錯(cuò)了陸。這里強(qiáng)調(diào)軌不要用晴retur緩n斥語句返回指溝向榮“族棧內(nèi)存勸”戲的指針,因嚇為該內(nèi)存在杯函數(shù)結(jié)束時(shí)角自動(dòng)消亡,康見示例數(shù)4.4顏。趨務(wù)char漂*GetS窄tring狐(void趨)汪{生char撿p[]弦="he況llow碌orld"擴(kuò);妻r(nóng)etu塘rnp;牙//蠅桂編譯器將提認(rèn)出警告臭}扇void繡Test4電(void勤)碼{紛char槍*str宿=NU欣LL;智str姨=龜GetS千tring蚊();/換/str辨緣的內(nèi)容是垃濕圾柜cout呼<<st緒r柏<<e類ndl;多}吐遇示例公4.4r盲eturn暴語句返回指閥向劣“蠻棧內(nèi)存丈”塞的指針盞邀絲慣用調(diào)試器逐病步跟蹤砍Test4同,發(fā)現(xiàn)執(zhí)行評str=臉GetS蘋tring翼語句后憐str股不再是燦NULL浮指針,但是鼠str速的內(nèi)容不是綱“抵hello脖襲world摧”避而是垃圾。裳如果把示例排4.4弊改寫成示例起4.5鴉,會(huì)怎么樣快?貼char全*GetS桂tring餐2(voi撫d)版{小char幅*p=敲"hel閑lowo討rld";拐retu壤rn盆p;遺}寸void脫Test5代(void撕)臨{遮char抵*str拾=NU燃LL;治s叢tr=演GetS司tring牧2();援cout集<<st選r<<鹿endl;搖}閃尖示例4.5斷retu謊rn卸語句返回?;至孔址芎瘮?shù)錯(cuò)Test5挺運(yùn)行雖然不囑會(huì)出錯(cuò),但汪是函數(shù)夏GetSt歌ring2另的設(shè)計(jì)概念評卻是錯(cuò)誤的攏。因?yàn)橹綠etSt糾ring2心內(nèi)的帽“水hello泡worl須d”危是常量字符腹串,位于靜脾態(tài)存儲(chǔ)區(qū),強(qiáng)它在程序生撐命期內(nèi)恒定等不變。無論落什么時(shí)候調(diào)儉用債GetSt盾ring2付,它返回的躬始終是同一核個(gè)晶“償只讀恥”金的內(nèi)存塊。兄疫5豈、杜絕晝“滾野指針愧”狀凈“挎野指針稠”素不是匯NULL素指針,是指窩向洽“膚垃圾學(xué)”蓄內(nèi)存的指針斃。人們一般奔不會(huì)錯(cuò)用旋NULL廳指針,因?yàn)榉庞妙檌f膽語句很容易污判斷。但是姓“訪野指針哪”庸是很危險(xiǎn)的她,殖if坑語句對它不躬起作用。旁“鹽野指針晴”需的成因主要屯有兩種:咸(抱1忘)指針變量咬沒有被初始淋化。任何指父針變量剛被猜創(chuàng)建時(shí)不會(huì)增自動(dòng)成為胡NULL娃指針,它的重缺省值是隨丙機(jī)的,它會(huì)廚亂指一氣。圓所以,指針槽變量在創(chuàng)建構(gòu)的同時(shí)應(yīng)當(dāng)墊被初始化,綢要么將指針普設(shè)置為末NULL蛾,要么讓它趁指向合法的暢內(nèi)存。例如腐char板*p=憲NULL;若char摔*str危=(ch濃ar*)宋mall蝦oc(10段0);旁(厚2洗)指針喂p呀被毒free怨或者讓delet耍e破之后,沒有料置為難NULL必,讓人誤以廣為認(rèn)p卸是個(gè)合法的寸指針。根(爸3努)指針操作切超越了變量宵的作用范圍劑。這種情況輔讓人防不勝摘防,示例程怠序如下:寫class穗A甚{鑰publ仁ic:擔(dān)voi該dFun死c(voi聞d){c貍out慘<<“枯Func廁ofcl洲assA座”<<胳endl;握}肚};患void下Test(怎void)村{巴A*p聰;折{焦A解a;匆p=季&倍a;//旗注意a郊的生命期末}怎p-邪>Func巷();/刊/p候是孟“刪野指針劫”恢}陳函數(shù)益Test氧在執(zhí)行語句吊p->Fu啊nc()筒時(shí),對象貫a隔已經(jīng)消失,竹而耗p護(hù)是指向公a旺的,所以勢p典就成了傅“謝野指針敘”啊。但奇怪的穿是我運(yùn)行這漆個(gè)程序時(shí)居蛇然沒有出錯(cuò)巧,這可能與點(diǎn)編譯器有關(guān)駁。耳6丙、有了儉mallo貓c/fre葛e損為什么還要絹new/d村e(cuò)lete處?剖毀mallo逮c收與仗free合是雞C++/C飽語言的標(biāo)準(zhǔn)唐庫函數(shù),皇new/d巨elete切是嘆C++惰的運(yùn)算符。絕它們都可用畜于申請動(dòng)態(tài)濟(jì)內(nèi)存和釋放產(chǎn)內(nèi)存。奧對于非螞內(nèi)部數(shù)據(jù)類尖型的對象而裹言,光用耀maloc釘/free慰無法滿足動(dòng)益態(tài)對象的要捆求。對象在棒創(chuàng)建的同時(shí)轉(zhuǎn)要自動(dòng)執(zhí)行億構(gòu)造函數(shù),烈對象在消亡弊之前要自動(dòng)據(jù)執(zhí)行析構(gòu)函雷數(shù)。由于蒼mallo別c/fre蓬e叨是庫函數(shù)而打不是運(yùn)算符膏,不在編譯僚器控制權(quán)限縱之內(nèi),不能慨夠把執(zhí)行構(gòu)沫造函數(shù)和析詢構(gòu)函數(shù)的任蒙務(wù)強(qiáng)加于仿mallo盾c/fre旨e之。召因此揮C++會(huì)語言需要一纏個(gè)能完成動(dòng)沿態(tài)內(nèi)存分配似和初始化工腿作的運(yùn)算符亮new裹,以及一個(gè)飽能完成清理課與釋放內(nèi)存留工作的運(yùn)算窮符游delet狡e護(hù)。注意蜜new/訂delet活e姨不是庫函數(shù)春。我們先看鳥一看討mallo葬c/fre蠢e乓和聲new/d難elete也如何實(shí)現(xiàn)對徒象的動(dòng)態(tài)內(nèi)源存管理,見峽示例禾6解。身class逢Obj游{晌publ婆ic:沫Obj元(void磁){co丟ut桑<<“辦Initi游aliza蛇tion”溫<<e汽ndl;川}襲~Ob皂j(voi嚴(yán)d){c愁out值<<“國Destr劈oy”<常<end百l;}常voi創(chuàng)dIni俊tiali狂ze(vo元id){屈c(diǎn)out攜<<“恩Initi門aliza探tion”塘<<e產(chǎn)ndl;巖}旨voi冶dDes秘troy(紗void)盡{cou豆t雁<<“銜Destr灣oy”<添<end謙l;}豎};墾void浮UseMa殲llocF駱ree(v蓄oid)槽{鑰Obj己*a=僵(obj需*)ma探lloc(癥sizeo芹f(obj到));/摘/登申請動(dòng)態(tài)內(nèi)勇存突a-撿>Init臣ializ思e();郵//釀初始化皆//墊…趴a-妖>相Destr悠oy();印//清臭除工作勤劃free(儉a);/例/析釋放內(nèi)存堂}優(yōu)void賀UseNe傭wDele蹈te(vo害id)氧{儀悼Obj*巴a=n棚ewOb皇j;//菠逃申請動(dòng)態(tài)內(nèi)傍存并且初始柄化曉//戴…額dele裳te臂a;/譜/偏清除并且釋寶放內(nèi)存技}啞通示例捏6久用幫mallo梯c/fre夕e瑞和圓new/d旺elete憑如何實(shí)現(xiàn)對魔象的動(dòng)態(tài)內(nèi)各存管理止類屬Obj穩(wěn)的函數(shù)搜Initi仔alize構(gòu)模擬了構(gòu)造碌函數(shù)的功能洗,函數(shù)踩Destr趁oy雖模擬了析構(gòu)賢函數(shù)的功能輸。函數(shù)滲UseMa量llocF超ree妖中,由于鼓mall載oc/fr雜ee案不能執(zhí)行構(gòu)璃造函數(shù)與析方構(gòu)函數(shù),必猛須調(diào)用成員菊函數(shù)富Initi余alize叫和栗Destr厭oy捏來完成初始刺化與清除工陰作。函數(shù)叛UseN蘇ewDel膚ete稻則簡單得多隔。搶所以我訂們不要企圖沖用銷mallo想c/fre粥e浸來完成動(dòng)態(tài)咳對象的內(nèi)存夏管理,應(yīng)該論用宣new/d泥elete幻。由于內(nèi)部朗數(shù)據(jù)類型的滴“愧對象些”良沒有構(gòu)造與花析構(gòu)的過程青,對它們而泳言贈(zèng)mallo足c/fre熱e低和趟new/d稀elete名是等價(jià)的??嗉热唤硁ew/d覺elete廟的功能完全燕覆蓋了拌mallo踩c/fre厲e萄,為什么巧C++浮不把之mallo樹c/fre引e魚淘汰出局呢能?這是因?yàn)榕糃++立程序經(jīng)常要曲調(diào)用搜C展函數(shù),而稅C奧程序只能用項(xiàng)mallo忌c/fre革e篇管理動(dòng)態(tài)內(nèi)師存。鑰如果用妖free匪釋放罵“屠new許創(chuàng)建的動(dòng)態(tài)閘對象相”只,那么該對顏象因無法執(zhí)瘡行析構(gòu)函數(shù)費(fèi)而可能導(dǎo)致針程序出錯(cuò)。痕如果用克delet排e飯釋放纖“致mallo絲c寶申請的動(dòng)態(tài)江內(nèi)存共”姻,理論上講構(gòu)程序不會(huì)出循錯(cuò),但是該音程序的可讀貓性很差。所套以徐new/d呢elete卸必須配對使跪用,運(yùn)mallo鎖c/fre蜻e情也一樣。膀擁7曬、內(nèi)存耗盡辮怎么辦?扔如果在申請西動(dòng)態(tài)內(nèi)存時(shí)吸找不到足夠娃大的內(nèi)存塊嗽,顯mallo勺c角和觀new奧將返回奴NULL奉指針,宣告濱內(nèi)存申請失矛敗。通常有邀三種方式處漠理邊“懷內(nèi)存耗盡晚”事問題。咱掀濫疊(雖1座)判斷指針汗是否為寶NU秘LL鬼,如果是則痛馬上用清retur減n雨語句終止本撲函數(shù)。例如泡:郵void誠Func(沫void)咳{書A誕*a=概new溉A;粱if(a團(tuán)==N傳ULL)條{聾ret舒urn;繁}蒜末…苦}尤(菠2菜)判斷指針脂是否為伸NULL貪,如果是則淋馬上用重exit(笑1)提終止整個(gè)程婚序的運(yùn)行。鼻例如:笛void銀Func(淺void)棗{即A*a乞=胸new視A;政if(a櫻==N織ULL)到{際cou孕t葛<<“銜Memor漫yExh衣auste漂d”<<顫endl課;親exi生t(1);悶}弄骨…匹}嗽粘悅(娘3塘)為變new辯和拴mallo班c企設(shè)置異常處兩理函數(shù)。例斷如鎖Visua僑lC++罪可以用碑_set_湯new_h井a(chǎn)nder夢函數(shù)為衣new誘設(shè)置用戶自幼己定義的異襲常處理函數(shù)蛛,也可以讓吹mallo鋤c桶享用與沈new杯相同的異常夫處理函數(shù)。錦詳細(xì)內(nèi)容請幼參考益C++金使用手冊。饞上述(赴1否)(萌2絞)方式使用撤最普遍。如順果一個(gè)函數(shù)去內(nèi)有多處需稻要申請動(dòng)態(tài)桑內(nèi)存,那么墻方式(子1矛)就顯得力口不從心(釋凍放內(nèi)存很麻芒煩),應(yīng)該狡用方式(裁2辦)來處理。熱很多人櫻不忍心用陸exit(綱1)觸,問:查“鏟不編寫出錯(cuò)鍵處理程序,嫌讓操作系統(tǒng)挽自己解決行流不行?答”溫不行。極如果發(fā)生傾“睜內(nèi)存耗盡誠”貸這樣的事情扔,一般說來主應(yīng)用程序已狀經(jīng)無藥可救示。如果不用塑exit(固1)綢把壞程序殺幕死,它可能摧會(huì)害死操作意系統(tǒng)。道理闖如同:如果泡不把歹徒擊鐘斃,歹徒在陽老死之前會(huì)黎犯下更多的至罪。內(nèi)有一個(gè)提很重要的現(xiàn)鐮象要告訴大柳家。對于德32漫位以上的應(yīng)拳用程序而言踢,無論怎樣渠使用白mallo雖c姻與竊new土,幾乎不可裹能導(dǎo)致日“驅(qū)內(nèi)存耗盡礦”茄。我在鴨Windo醬ws夜98下用V昏isual秤C++圓編寫了測試裙程序,見示堵例社7鳳。這個(gè)程序遵會(huì)無休止地洪運(yùn)行下去,奔根本不會(huì)終盆止。因?yàn)閬G32咸位操作系統(tǒng)尾支持訊“街虛存饑”靠,內(nèi)存用完梨了,自動(dòng)用鋒硬盤空間頂圣替。我只聽?wèi)偷接脖P嘎吱寶嘎吱地響,胸Windo碑w98峽已經(jīng)累得對希鍵盤、鼠標(biāo)籮毫無反應(yīng)。酬我可以霉得出這么一秤個(gè)結(jié)論:對柳于季32平位以上的應(yīng)獄用程序,隆“拿內(nèi)存耗盡皮”模錯(cuò)誤處理程停序毫無用處艱。這下可把黑Unix專和元Windo鏈ws薄程序員們樂歇壞了:反正碰錯(cuò)誤處理程常序不起作用卵,我就不寫陣了,省了很位多麻煩。并我不想遣誤導(dǎo)讀者,早必須強(qiáng)調(diào):書不加錯(cuò)誤處拖理將導(dǎo)致程葬序的質(zhì)量很旁差,千萬不伴可因小失大瀉。里void涉main(耽void)凈{酷floa撤t馳*p=紙NULL澆;仁whil無e(TRU容E)桑{潔p=疫new階float稻[1000傷000];趙cou資t孔<<“炊eatm胳emory忠”<<臭endl;候if(同p==NU罪L(fēng)L)淋ex浙it(1)匆;塊}垮}糾示例盞7崇試圖耗盡操汪作系統(tǒng)的內(nèi)岸存智興屆8仔、作mallo沸c/fre蔽e世的使用要點(diǎn)細(xì)函數(shù)刑mallo認(rèn)c她的原型如下董:磨void棋*mal扭loc(s堂ize_t婦size陷);香用涂mallo僑c奪申請一塊長疲度為貧lengt蛙h質(zhì)的整數(shù)類型遞的內(nèi)存,程伐序如下:揀int*辮p=(大int*蜂)mal禾loc(s混izeof艇(int)謎*le容ngth)擺;格我們應(yīng)咱當(dāng)把注意力繡集中在兩個(gè)嘗要素上:貍“戲類型轉(zhuǎn)換售”趙和貼“坊sizeo番f”驕。戚拆*mal校lo據(jù)c即返回值的類忌型是恨void鍛*梳,所以在調(diào)喜用做mallo掃c裁時(shí)要顯式地炮進(jìn)行類型轉(zhuǎn)肚換,將粒void遭*除轉(zhuǎn)換成所需雞要的指針類獲型。編拜*mal扯loc腰函數(shù)本身并糾不識(shí)別要申輪請的內(nèi)存是棍什么類型,昆它只關(guān)心內(nèi)鼠存的總字節(jié)慧數(shù)。我們通譽(yù)常記不住衫int,譽(yù)float絕等數(shù)據(jù)類型迷的變量的確鳳切字節(jié)數(shù)。謝例如訪int貢變量在畏16鐵位系統(tǒng)下是輪2痛個(gè)字節(jié),在含32按位下是叮4鄰個(gè)字節(jié);而及float籃變量在謹(jǐn)16須位系統(tǒng)下是型4襪個(gè)字節(jié),在易32觸位下也是姓4杰個(gè)字節(jié)。最視好用以下程砌序作一次測兩試:速cout魄<<si環(huán)zeof(登char)擇<<e絡(luò)ndl;站cout濤<<si只zeo愚f(int統(tǒng))<<墊endl;疊cout裙<<si體zeof(友unsig損nedi錘nt)<秤<end梅l;俘cout杰<<si憶zeof(壘long)膝<<e顆ndl;芬cout倍<<si女zeof(給unsig染nedl男ong)南<<en苦dl;粱cout汽<<si挽zeof(肝float豐)<<殼endl;笨cout麗<<si蒙zeof(車doubl搖e)<<柏endl潤;教cout暑<<si篩zeof(俯void枝*)<<賴endl聚;隊(duì)在區(qū)mallo祝c桶的邁“秤()”馬中使用族sizeo施f鏡運(yùn)算符是良診好的風(fēng)格,秋但要當(dāng)心有庸時(shí)我們會(huì)昏相了頭,寫出旨p=喇mallo孔c(siz喝eof(p值))柱這樣的程序瘋來。牧貴*宰函數(shù)掏free個(gè)的原型如下刷:芝void呆free(矛void烈*me祥mbloc糖k);驢為什么閉free巴函數(shù)不象倚mallo棍c彈函數(shù)那樣復(fù)援雜呢?這是登因?yàn)橹羔樍鵳迫的類型以及師它所指的內(nèi)雅存的容量事尋先都是知道姓的,語句桂free(夾p)腐能正確地
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(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ǔ)空間,僅對用戶上傳內(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 嘉禾縣人民法院2026年公開招聘聘用制審判輔助人員、新媒體運(yùn)營人員備考題庫帶答案詳解
- 2026年民航專業(yè)工程質(zhì)量監(jiān)督總站招聘易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 2026年武漢市政務(wù)服務(wù)中心管理辦公室(市民之家)招考易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 2026年株洲市天元區(qū)城市管理監(jiān)督指揮中心招考易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 2026年杭州市西湖區(qū)社會(huì)服務(wù)管理中心招考編外人員易考易錯(cuò)模擬試題(共500題)試卷后附參考答案
- 生產(chǎn)車間環(huán)保管理制度
- 中藥飲片安全生產(chǎn)制度
- 車間生產(chǎn)部管理制度
- 生產(chǎn)制造企業(yè)規(guī)章制度
- 光伏電站生產(chǎn)報(bào)告制度
- 2026年1月福建廈門市集美區(qū)后溪鎮(zhèn)衛(wèi)生院補(bǔ)充編外人員招聘16人筆試備考題庫及答案解析
- 重慶市渝中區(qū)(2025年)輔警協(xié)警筆試筆試真題(附答案)
- 暴雪車輛行駛安全培訓(xùn)課件
- 2026年七臺(tái)河職業(yè)學(xué)院單招綜合素質(zhì)筆試模擬試題帶答案解析
- 2026年吉林司法警官職業(yè)學(xué)院單招職業(yè)技能考試備考試題帶答案解析
- 2025內(nèi)蒙古潤蒙能源有限公司招聘22人考試題庫附答案解析(奪冠)
- 2026年國家電網(wǎng)招聘之電網(wǎng)計(jì)算機(jī)考試題庫500道有答案
- 年味課件教學(xué)課件
- 中國臨床腫瘤學(xué)會(huì)(csco)胃癌診療指南2025
- 廣東省廣州市2025年上學(xué)期八年級(jí)數(shù)學(xué)期末考試試卷附答案
- 手機(jī)鋪貨協(xié)議書
評論
0/150
提交評論