下載本文檔
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
指
針
指針與內(nèi)存指針如何創(chuàng)建動(dòng)態(tài)內(nèi)存。指針如何釋放所創(chuàng)建的動(dòng)態(tài)內(nèi)存野指針的處理辦法。熟練的掌握指針如何創(chuàng)建動(dòng)態(tài)內(nèi)存和釋放所創(chuàng)建的動(dòng)態(tài)內(nèi)存,熟練的掌握野指針的處理辦法。1在C++程序中,一些變量在整個(gè)程序中都是可見(jiàn)的,稱(chēng)為全局變量。一些只能在一個(gè)函數(shù)中可知,稱(chēng)為局部變量。1.6.9指針與程序內(nèi)存2一個(gè)程序?qū)⒉僮飨到y(tǒng)分配給其運(yùn)行的內(nèi)存塊分為4個(gè)區(qū)域:1)代碼區(qū),存放系統(tǒng)的代碼,即程序中的各個(gè)函數(shù)代碼塊。2)全局?jǐn)?shù)據(jù)區(qū),存放程序的全局?jǐn)?shù)據(jù)和靜態(tài)數(shù)據(jù)。內(nèi)存在程序編譯的時(shí)候就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。在C/C++程序中,不管是局部變量,全局變量、或是動(dòng)態(tài)變量,在內(nèi)存中都占用一定的空間,但是它們占用不同的空間。1.6.9指針與程序內(nèi)存33)堆區(qū),存放程序的動(dòng)態(tài)數(shù)據(jù)。程序在運(yùn)行的時(shí)候用new申請(qǐng)任意多的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用delete釋放內(nèi)存。4)棧區(qū),存放程序的局部數(shù)據(jù),即各個(gè)函數(shù)中的數(shù)據(jù)。在執(zhí)行函數(shù)時(shí),函數(shù)內(nèi)局部變量的存儲(chǔ)單元都可以在棧上創(chuàng)建,函數(shù)執(zhí)行結(jié)束時(shí)這些存儲(chǔ)單元自動(dòng)被釋放。1.6.9指針與程序內(nèi)存4在C++中,申請(qǐng)和釋放堆中分配的存貯空間,分別使用new和delete的兩個(gè)運(yùn)算符來(lái)完成:申請(qǐng)內(nèi)存使用new:例如:1、int*pi=newint(0);
它與下列代碼序列大體等價(jià):
2、intival=0,*pi=&ival;區(qū)別:pi所指向的變量是由庫(kù)操作符new()分配的,位于程序的堆區(qū)中,并且該對(duì)象未命名。指針變量名=new類(lèi)型名(初始化式);1.6.10指針與動(dòng)態(tài)內(nèi)存5new運(yùn)算符返回的是一個(gè)指向所分配類(lèi)型變量(對(duì)象)的指針。對(duì)所創(chuàng)建的變量或?qū)ο?,都是通過(guò)該指針來(lái)間接操作的,而動(dòng)態(tài)創(chuàng)建的對(duì)象本身沒(méi)有名字。例如以下代碼:int*pi=newint(12);其中pi為這個(gè)指針的名稱(chēng),而12這個(gè)整型并沒(méi)對(duì)象,pi保存了12所在的內(nèi)存的內(nèi)存地址。1.6.10指針與動(dòng)態(tài)內(nèi)存6在堆中建立動(dòng)態(tài)一維數(shù)組原型如下:注意:“下標(biāo)表達(dá)式”不是常量表達(dá)式,即它的值不必在編譯時(shí)確定,可以在運(yùn)行時(shí)確定。指針變量名=new類(lèi)型名[下標(biāo)表達(dá)式];例如以下代碼:intival=10;int*pi=newint[ival];1.6.10指針與動(dòng)態(tài)內(nèi)存7在代碼欄編寫(xiě)以下代碼,編譯并查看輸出:#include<iostream>usingnamespacestd;voidmain(){intn;char*pc;cout<<"請(qǐng)輸入動(dòng)態(tài)數(shù)組的元素個(gè)數(shù)"<<endl;cin>>n;pc=newchar[n];strcpy(pc,"veryGood");cout<<pc<<endl;delete[]pc;system(“pause”);}1.6.10指針與動(dòng)態(tài)內(nèi)存8在堆中釋放指針?biāo)鶆?chuàng)建的內(nèi)存原型如下:堆空間申請(qǐng)、釋放演示:⑴.用初始化式(initializer)來(lái)顯式初始化int*pi=newint(0);⑵.當(dāng)pi生命周期結(jié)束時(shí),必須釋放pi所指向的目標(biāo):deletepi;delete指針變量名;注意這時(shí)釋放了pi所指的目標(biāo)的內(nèi)存空間,也就是撤銷(xiāo)了該目標(biāo),稱(chēng)動(dòng)態(tài)內(nèi)存釋放(dynamicmemorydeallocation),但指針pi本身并沒(méi)有撤銷(xiāo),它自己仍然存在,該指針?biāo)純?nèi)存空間并未釋放,需要注意的是任何類(lèi)型指針的都會(huì)占用四個(gè)字節(jié)的內(nèi)存。1.6.10指針與動(dòng)態(tài)內(nèi)存9特別需要注意的是,如果該指針又指向了別處,那么在釋放以前務(wù)必要保證指針從新指回原來(lái)的內(nèi)存地址:例如以下代碼,運(yùn)行時(shí)程序會(huì)奔潰:#include<iostream>usingnamespacestd;voidmain(){ int*pi=newint(9); intival=5; pi=&ival; deletepi; system(“pause”);}1.6.10指針與動(dòng)態(tài)內(nèi)存10在堆中釋放指針?biāo)鶆?chuàng)建的數(shù)組內(nèi)存原型如下:注意:方括號(hào)非常重要的,如果delete語(yǔ)句中少了方括號(hào),因編譯器認(rèn)為該指針是指向數(shù)組第一個(gè)元素的,會(huì)產(chǎn)生回收不徹底的問(wèn)題(只回收了第一個(gè)元素所占空間),加了方括號(hào)后就轉(zhuǎn)化為指向數(shù)組的指針,回收整個(gè)數(shù)組。delete[]的方括號(hào)中不需要填數(shù)組元素?cái)?shù),系統(tǒng)自知。即使寫(xiě)了,編譯器也忽略。delete[]指向該數(shù)組的指針變量名1.6.10指針與動(dòng)態(tài)內(nèi)存11如果指向數(shù)組的指針移動(dòng)了,或者指向了別的內(nèi)存地址,那么在釋放前務(wù)必要將該指針回歸原位,最快捷的辦法是做原始內(nèi)存地址的備份。例如以下代碼,演示了如何做原始內(nèi)存地址的備份:#include<iostream>usingnamespacestd;voidmain(){ int*pi=newint[10]; int*temp=pi; intival=20; pi=&ival; pi=temp; delete[]pi; system(“pause”);}1.6.10指針與動(dòng)態(tài)內(nèi)存12編譯器不能自動(dòng)發(fā)現(xiàn)內(nèi)存錯(cuò)誤,通常是在程序運(yùn)行時(shí)才能捕捉到。常見(jiàn)的內(nèi)存錯(cuò)誤及對(duì)策:1)內(nèi)存分配未成功,卻使用了它。int*pB;*pB=10;解決辦法:在使用內(nèi)存之前檢查指針是否為NULL。assert(p!=NULL)if(p==NULL)或if(p!=NULL)1.6.10指針與動(dòng)態(tài)內(nèi)存132)內(nèi)存分配雖然成功,但是尚未初始化就引用它。解決辦法:無(wú)論用何種方式創(chuàng)建數(shù)組,都別忘了賦初值,即便是賦零值也不可省略。例如以下代碼:#include<iostream>usingnamespacestd;voidmain(){ int*pi=newint[10]; for(inti=0;i<10;i++) cout<<pi[i]<<endl; system(“pause”);}1.6.10指針與動(dòng)態(tài)內(nèi)存143)內(nèi)存分配成功并且已經(jīng)初始化,但操作越過(guò)了內(nèi)存的邊界。charstrText[8];sprintf(strText,"Thisisalongtext!");解決辦法:留心數(shù)組的大小,避免數(shù)組操作越界。1.6.10指針與動(dòng)態(tài)內(nèi)存155)釋放了內(nèi)存卻繼續(xù)使用它程序中的對(duì)象調(diào)用關(guān)系過(guò)于復(fù)雜,實(shí)在難以弄清楚某個(gè)對(duì)象是否已經(jīng)釋放了內(nèi)存。解決辦法:應(yīng)該重新設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),從根本上解決對(duì)象管理的混亂局面。4)忘記了釋放內(nèi)存,造成內(nèi)存泄露。含有這種錯(cuò)誤的函數(shù)每被調(diào)用一次就丟失一塊內(nèi)存。解決辦法:動(dòng)態(tài)內(nèi)存的申請(qǐng)與釋放必須配對(duì),程序中new與delete的使用次數(shù)一定要相同,否則肯定有錯(cuò)誤。1.6.10指針與動(dòng)態(tài)內(nèi)存16使用delete釋放了內(nèi)存后,沒(méi)有將指針設(shè)置為NULL。導(dǎo)致產(chǎn)生“野指針”?!耙爸羔槨辈皇荖ULL指針,是指向“垃圾”內(nèi)存的指針。char*pStrBuffer=newchar[256];delete[]pStrBuffer;*pStrBuffer=NULL;1.6.10指針與動(dòng)態(tài)內(nèi)存17內(nèi)存操作注意事項(xiàng):1)用new申請(qǐng)內(nèi)存之后,應(yīng)該立即檢查指針值是否為NULL。防止使用指針值為NULL的內(nèi)存。2)不要忘記為數(shù)組和動(dòng)態(tài)內(nèi)存賦初值。防止將未被初始化的內(nèi)存作為右值使用。3)避免數(shù)組或指針的下標(biāo)越界,特別要當(dāng)心發(fā)生“多1”或者“少1”操作。4)動(dòng)態(tài)內(nèi)存的申請(qǐng)與釋放必須配對(duì),防止內(nèi)存泄漏。5)用delete釋放了內(nèi)存之后,立即將指針設(shè)置為NULL,防止產(chǎn)生“野指針”。1.6.10指針與動(dòng)態(tài)內(nèi)存18指針變量自身也有自己的內(nèi)存,由于只需要保持一個(gè)內(nèi)存地址,所以任何類(lèi)型的指針大小都是四個(gè)字節(jié)。在代碼欄編寫(xiě)以下代碼,編譯并查看輸出:#include<iostream>usingnamespacestd;voidmain(){ char*pc; int*pi; short*ps; double*pd; cout<<sizeof(pc)<<endl; cout<<sizeof(pi)<<endl; cout<<sizeof(ps)<<endl; cout<<sizeof(pd)<<endl; system(“pause”);}1.6.11指針的內(nèi)存地址19如果要保存指針的內(nèi)存地址,則需要使用到二級(jí)指針。在代碼欄編寫(xiě)以下代碼,編譯并查看輸出:#include<iostream>usingnamespacestd;voidmain(){ intival=10; int*pi=&ival; int**ppi=π cout<<&pi<<endl; cout<<ppi<<endl; system(“pause”);}1.6.11指針的內(nèi)存地址20void類(lèi)型的指針可以保存任何類(lèi)型數(shù)據(jù)的內(nèi)存地址,只不過(guò)在訪問(wèn)數(shù)據(jù)或者修改數(shù)據(jù)的時(shí)候,需要將指針類(lèi)型轉(zhuǎn)換為所保存的數(shù)據(jù)類(lèi)型。在代碼欄編寫(xiě)以下代碼,編譯并查看輸出:#include<iostream>usingnamespacestd;voidmain(){ intival=10; int*pi=&ival; void*pv=&ival; cout<<pi<<endl; cout<<pv<<endl; cout<<*(int*)pv<<endl; system(“pause”);}1.6.12void類(lèi)型的指針21在32位機(jī)器中整型與指針都占4個(gè)字節(jié),內(nèi)存的表現(xiàn)方式也都是二進(jìn)制整數(shù),但是整型和指針?biāo)硎镜臄?shù)據(jù)類(lèi)型不同。在代碼欄編寫(xiě)以下代碼,編譯并查看輸出,可以看到一個(gè)編譯錯(cuò)誤,無(wú)法從整型轉(zhuǎn)換為整型的指針:#include<iostream>#include<windows.h>usingnamespacestd;voidmain(){ intival=0x18ff28; int*pi=ival; system(“pause”);}1.6.12void類(lèi)型的指針22但是整型類(lèi)型被強(qiáng)制轉(zhuǎn)換為整型指針類(lèi)型后,也可以給指針賦值,這個(gè)時(shí)候要注意的是指針保存的并不是整型數(shù)據(jù)所在的內(nèi)存地址。在代碼欄編寫(xiě)以下代碼,編譯并查看輸出:#include<iostream>#include<windows.h>usingnamespacestd;voidmain(){ intival=0x18ff00; int*pi=(int*)ival; cout<<pi<<endl; cout<<*pi<<endl; cout<<&ival<<endl; system(“pause”);}1.6.12void類(lèi)型的指針23本節(jié)介紹了如何使用指針創(chuàng)建動(dòng)態(tài)內(nèi)存的辦法,以及如何釋放動(dòng)態(tài)內(nèi)存和野指針的處理辦法。運(yùn)行int*pi=new
int(9);inti
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 門(mén)市出租合同范本
- 園林花木租賃合同格式
- 庭院房購(gòu)房合同范本2024年
- 砌筑工程-磚砌體施工
- 股權(quán)投資公司抵押擔(dān)保借款合同范本
- 關(guān)于離婚協(xié)議書(shū)范本建議
- 家政服務(wù)人員勞動(dòng)合同案例
- 2024年幼兒食材配送協(xié)議樣本
- 識(shí)別并規(guī)避勞動(dòng)合同中的霸王條款
- 2024版產(chǎn)品買(mǎi)賣(mài)協(xié)議書(shū)格式示例
- 安徽省合肥市第五十中學(xué)西校區(qū)2024-2025學(xué)年期中考試七年級(jí)數(shù)學(xué)試題(無(wú)答案)
- 滬教版四年級(jí)上冊(cè)期中復(fù)習(xí)數(shù)學(xué)試卷(一)
- 廣東省廣州市2024-2025學(xué)年上學(xué)期八年級(jí)數(shù)學(xué)期中復(fù)習(xí)試卷
- TWSJD 66-2024 放射工作人員職業(yè)健康檢查技術(shù)指南
- 醫(yī)院介紹課件模板
- 20世紀(jì)時(shí)尚流行文化智慧樹(shù)知到期末考試答案2024年
- 第四章-國(guó)防動(dòng)員
- 第一講軍事思想概論
- 普及人民代表大會(huì)制度知識(shí)競(jìng)賽試題庫(kù)(1000題和答案)
- 蘭亭序中楷毛筆臨摹字帖(可打印)
- 單相智能電表硬件電路設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論