動(dòng)態(tài)內(nèi)存分配_第1頁(yè)
動(dòng)態(tài)內(nèi)存分配_第2頁(yè)
動(dòng)態(tài)內(nèi)存分配_第3頁(yè)
動(dòng)態(tài)內(nèi)存分配_第4頁(yè)
動(dòng)態(tài)內(nèi)存分配_第5頁(yè)
已閱讀5頁(yè),還剩40頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、5.7 多級(jí)指針與多維數(shù)組多級(jí)指針與多維數(shù)組 (選讀)(選讀)多級(jí)指針的概念:多級(jí)指針的概念:多級(jí)指針可對(duì)應(yīng)于多維數(shù)組,這種指針變量中存的是另多級(jí)指針可對(duì)應(yīng)于多維數(shù)組,這種指針變量中存的是另一個(gè)指針變量的地址,其說(shuō)明如下:一個(gè)指針變量的地址,其說(shuō)明如下:int val=10;int *ptr=&val;int *pptr=&ptr;int *ppptr=&pptr; /是多少級(jí)指針就有多少是多少級(jí)指針就有多少*號(hào)號(hào)這里這里val值為值為10,*ptr值也為值也為10,*pptr的值和的值和*ppptr的值均為的值均為10。(。(注意:注意:這段文字中的這段文字中的*號(hào)是

2、運(yùn)號(hào)是運(yùn)算符,稱(chēng)算符,稱(chēng)間接引用運(yùn)算符間接引用運(yùn)算符。與定義中的。與定義中的*號(hào)意義不同,號(hào)意義不同,定義中的定義中的是指針說(shuō)明符。)是指針說(shuō)明符。)【例【例5.13】多級(jí)指針多級(jí)指針int main()int val=66;int *pval = &val;int *ppval = &pval; coutval=valn*ppval= *ppvaln; *ppval=18;coutval=valn*ppval=“ *ppvalendl;return 0;程序中程序中ppval稱(chēng)為多級(jí)指針,稱(chēng)為多級(jí)指針,val、pval和和ppval之間的關(guān)之間的關(guān)系參見(jiàn)圖系參見(jiàn)圖5.7。【例

3、【例5.13】多級(jí)指針(選讀)】多級(jí)指針(選讀)變量變量ppval變量變量pval變量變量val圖圖5.7 5.7 多級(jí)指針多級(jí)指針5.7 多級(jí)指針與多維數(shù)組多級(jí)指針與多維數(shù)組 (選讀)(選讀)指針兩要素:指針兩要素: 指向數(shù)組(元素)類(lèi)型指向數(shù)組(元素)類(lèi)型的的指針指針,與一維數(shù)組名是等,與一維數(shù)組名是等效的:效的:int a10, *pa =a;則寫(xiě)則寫(xiě)pa0 ,就是,就是a0;*pa,即,即a0;*(pa+1) 和和pa1 ,都代表,都代表a1。 指針有兩要素:地址和所指向目標(biāo)的數(shù)據(jù)類(lèi)型。指針有兩要素:地址和所指向目標(biāo)的數(shù)據(jù)類(lèi)型。a 與與pa 兩者都是一樣的,所以?xún)烧叨际且粯拥?,所以pa

4、 可以替代可以替代a。5.7 多級(jí)指針與多維數(shù)組多級(jí)指針與多維數(shù)組 (選讀)(選讀)指向一維數(shù)組的指針的定義如下:指向一維數(shù)組的指針的定義如下:數(shù)據(jù)類(lèi)型數(shù)據(jù)類(lèi)型 (* 指針變量名指針變量名)n;這里數(shù)組元素的個(gè)數(shù)這里數(shù)組元素的個(gè)數(shù)n不可省略。因是指向指針的指針,稱(chēng)二不可省略。因是指向指針的指針,稱(chēng)二級(jí)指針。級(jí)指針。 二維數(shù)組與指針:二維數(shù)組與指針: 二維數(shù)組是數(shù)組元素為一維數(shù)組的數(shù)組,所以等效的指二維數(shù)組是數(shù)組元素為一維數(shù)組的數(shù)組,所以等效的指針類(lèi)型應(yīng)該是針類(lèi)型應(yīng)該是指向一維數(shù)組的指針類(lèi)型指向一維數(shù)組的指針類(lèi)型。如有:。如有:int x2d34=1,2,3,4,5,6,7,8,9,10,11,

5、12;int (*pt)4=x2d;則指針則指針pt 和和x2d 是等效的。它們表示的首地址一樣,所指目是等效的。它們表示的首地址一樣,所指目標(biāo)類(lèi)型也一樣,標(biāo)類(lèi)型也一樣,pt 可以代替可以代替x2d,就象,就象pa代替代替a一樣。一樣。 指向行方向指向行方向x2d00 x2d12x2d02x2d03x2d10 x2d11x2d20 x2d01x2d23x2d21x2d0 x2d+1(或或pt+1)x2d22x2d1x2d2x2d13x2d(或(或pt)指向列方向指向列方向x2d+2(或或pt+2)圖圖5.8 二維數(shù)組剖析二維數(shù)組剖析x2d指向的是一個(gè)由指針組成的數(shù)組,包括指向的是一個(gè)由指針組成

6、的數(shù)組,包括x2d0,x2d1和和x2d2 。由此可見(jiàn),存儲(chǔ)二維數(shù)組還必須保存一些訪問(wèn)數(shù)組。由此可見(jiàn),存儲(chǔ)二維數(shù)組還必須保存一些訪問(wèn)數(shù)組元素的輔助信息,如:元素的輔助信息,如:x2d0,x2d1和和x2d2。 在這里在這里x2d即即&x2d0,即,即x2d中放的是中放的是第第0行行x2d0的地的地址址,其所指,其所指目標(biāo)是由目標(biāo)是由4個(gè)整型數(shù)組成的一維數(shù)組個(gè)整型數(shù)組成的一維數(shù)組,占內(nèi)存,占內(nèi)存16個(gè)個(gè)字節(jié)。字節(jié)。pt等效等效x2d,*pt即即x2d0。二維數(shù)組剖析:二維數(shù)組剖析:表示形式表示形式含義含義X2d, & x2d0二維數(shù)組名表示指向第二維數(shù)組名表示指向第0行的指針行的

7、指針x2d0 ,*(x2d+0),* x2d, & x2d00 指向二維數(shù)組第指向二維數(shù)組第0行第行第0列元素的指針列元素的指針x2d+i, & x2di指向二維數(shù)組第指向二維數(shù)組第i行的指針行的指針x2di, *( x2d+i)指向二維數(shù)組第指向二維數(shù)組第i行第行第0列元素的指針列元素的指針x2di+j,*( x2d+i)+j, & x2dij指向二維數(shù)組第指向二維數(shù)組第i行第行第j列元素的指針列元素的指針*(x2di+j),*(*( x2d+i)+j), x2dij二維數(shù)組第二維數(shù)組第i行第行第j列元素的值列元素的值表表5.1 數(shù)組與指針的等價(jià)關(guān)系數(shù)組與指針的等價(jià)關(guān)

8、系指向行方向指向行方向x2d00 x2d12x2d02x2d03x2d10 x2d11x2d20 x2d01x2d23x2d21x2d0 x2d+1(或或pt+1)x2d22x2d1x2d2x2d13x2d(或(或pt)指向列方向指向列方向x2d+2(或或pt+2)注意:上下兩圖表對(duì)比注意:上下兩圖表對(duì)比5.7 多級(jí)指針與多維數(shù)組多級(jí)指針與多維數(shù)組 (選讀)(選讀)【例【例5.14】用指向二維數(shù)組基本元素的指針變用指向二維數(shù)組基本元素的指針變量,和用指向組成二維數(shù)組的一維數(shù)組的指針量,和用指向組成二維數(shù)組的一維數(shù)組的指針變量輸出二維數(shù)組全部基本元素。變量輸出二維數(shù)組全部基本元素。 用用指向數(shù)組

9、元素的指針指向數(shù)組元素的指針把數(shù)組傳遞到函數(shù)里,把數(shù)組傳遞到函數(shù)里,同時(shí)傳遞同時(shí)傳遞行列信息行列信息,就可以,就可以實(shí)現(xiàn)通用性實(shí)現(xiàn)通用性?!纠纠?.14】用指針變量輸出二維數(shù)組(選讀)】用指針變量輸出二維數(shù)組(選讀)int main( ) int a36=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18; int * ptr,i,j; ptr=&a00 ; /或或 ptr = *a; 而不能而不能ptr = a; for(i=0;i18;i+)cout*(ptr+i)t;if(i%6=5) coutendl; coutendl; int (*

10、ptr1)6; /注意注意 ptr1是指向包含是指向包含6個(gè)整型元素的一維數(shù)組的指針個(gè)整型元素的一維數(shù)組的指針 ptr1=a; for(i=0;i3;i+) for(j=0;j6;j+) cout*(*(ptr1+i)+j)t;coutendl; return 0;指針數(shù)組指針數(shù)組n數(shù)組的元素是指針型數(shù)組的元素是指針型例:例:Point *pa2; 由由pa0,pa1兩個(gè)指針組成兩個(gè)指針組成利用指針數(shù)組存放單位矩陣?yán)弥羔様?shù)組存放單位矩陣#include using namespace std;void main()int line1=1,0,0; /聲明數(shù)組,矩陣的第一行聲明數(shù)組,矩陣的第一

11、行int line2=0,1,0; /聲明數(shù)組,矩陣的第二行聲明數(shù)組,矩陣的第二行int line3=0,0,1; /聲明數(shù)組,矩陣的第三行聲明數(shù)組,矩陣的第三行int *p_line3;/聲明整型指針數(shù)組聲明整型指針數(shù)組p_line0=line1;/初始化指針數(shù)組元素初始化指針數(shù)組元素p_line1=line2;p_line2=line3; coutMatrix test:endl; /輸出單位矩陣輸出單位矩陣for(int i=0;i3;i+)/對(duì)指針數(shù)組元素循環(huán)對(duì)指針數(shù)組元素循環(huán) for(int j=0;j3;j+)/對(duì)矩陣每一行循環(huán)對(duì)矩陣每一行循環(huán) coutp_lineij ; cou

12、t成員名成員名ptr-getx() 相當(dāng)于相當(dāng)于 (*ptr).getx();對(duì)象指針應(yīng)用舉例對(duì)象指針應(yīng)用舉例int main() Point A(5,10); Point *ptr; ptr=&A; int x; x=ptr-GetX(); coutxendl; return 0;void類(lèi)型指針的使用類(lèi)型指針的使用void vobject; /錯(cuò),不能聲明錯(cuò),不能聲明void類(lèi)型的變量類(lèi)型的變量void *pv; /對(duì),可以聲明對(duì),可以聲明void類(lèi)型的指針類(lèi)型的指針int *pint; int i;void main() /void類(lèi)型的函數(shù)沒(méi)有返回值類(lèi)型的函數(shù)沒(méi)有返回值pv =

13、 &i; /void類(lèi)型指針指向整型變量類(lèi)型指針指向整型變量 / void指針賦值給指針賦值給int指針需要類(lèi)型強(qiáng)制轉(zhuǎn)換指針需要類(lèi)型強(qiáng)制轉(zhuǎn)換: pint = (int *)pv; 第七章第七章 動(dòng)態(tài)內(nèi)存分配動(dòng)態(tài)內(nèi)存分配7.17.1自由存儲(chǔ)區(qū)內(nèi)存分配自由存儲(chǔ)區(qū)內(nèi)存分配 7.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存內(nèi)存的分配與釋放的分配與釋放 7.1.2自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)對(duì)象對(duì)象與構(gòu)造函數(shù)與構(gòu)造函數(shù) 7.1.3 淺復(fù)制與深復(fù)制淺復(fù)制與深復(fù)制 靜態(tài)存儲(chǔ)分配:靜態(tài)存儲(chǔ)分配:無(wú)論全局或局部變量無(wú)論全局或局部變量( (對(duì)象對(duì)象) ),編,編譯器在譯器在編譯時(shí)編譯時(shí)都可以根據(jù)該變量都可以根據(jù)該變量( (對(duì)象

14、對(duì)象) )的類(lèi)型知道所需內(nèi)存空間的類(lèi)型知道所需內(nèi)存空間的大小,從而系統(tǒng)在適當(dāng)?shù)臅r(shí)候的大小,從而系統(tǒng)在適當(dāng)?shù)臅r(shí)候?yàn)樗鼈兎峙浯_定的存儲(chǔ)空間。尤為它們分配確定的存儲(chǔ)空間。尤其是數(shù)組。其是數(shù)組。動(dòng)態(tài)存儲(chǔ)分配:動(dòng)態(tài)存儲(chǔ)分配:有些操作對(duì)象只有在程序有些操作對(duì)象只有在程序運(yùn)行時(shí)運(yùn)行時(shí)才能確定,這樣編譯器在編譯時(shí)才能確定,這樣編譯器在編譯時(shí)就無(wú)法為他們預(yù)定存儲(chǔ)空間,只就無(wú)法為他們預(yù)定存儲(chǔ)空間,只能在程序運(yùn)行時(shí),系統(tǒng)根據(jù)運(yùn)行能在程序運(yùn)行時(shí),系統(tǒng)根據(jù)運(yùn)行時(shí)的要求進(jìn)行內(nèi)存分配,稱(chēng)為動(dòng)時(shí)的要求進(jìn)行內(nèi)存分配,稱(chēng)為動(dòng)態(tài)存儲(chǔ)分配。動(dòng)態(tài)分配都在態(tài)存儲(chǔ)分配。動(dòng)態(tài)分配都在自由自由存儲(chǔ)區(qū)存儲(chǔ)區(qū)中進(jìn)行。中進(jìn)行。動(dòng)態(tài)申請(qǐng)內(nèi)存操作符動(dòng)態(tài)

15、申請(qǐng)內(nèi)存操作符 new格式格式: :new new 類(lèi)型名類(lèi)型名T T(初值列表)(初值列表)功能:功能:在程序執(zhí)行期間,申請(qǐng)用于存放在程序執(zhí)行期間,申請(qǐng)用于存放T類(lèi)型對(duì)象的內(nèi)存空類(lèi)型對(duì)象的內(nèi)存空間,并依初值列表賦以初值。間,并依初值列表賦以初值。結(jié)果值結(jié)果值:成功:成功:T類(lèi)型的指針,指向新分配的內(nèi)存。失敗:類(lèi)型的指針,指向新分配的內(nèi)存。失?。?(NULL)例:例: int *p1=new int; int *p2=new int(90); int *p3=new int90;釋放內(nèi)存操作符釋放內(nèi)存操作符delete格式格式: :delete delete 指針指針P P功能:功能:釋放指針

16、釋放指針P所指向的內(nèi)存。所指向的內(nèi)存。P必須是必須是new操作的操作的返回值。返回值。delete p1;delete p3; 7.1.17.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)i演示:演示:用初始化式用初始化式(initializer)(initializer)來(lái)顯式初始化來(lái)顯式初始化 int *pi=new int(0);當(dāng)當(dāng)pipi生命周期結(jié)束時(shí),生命周期結(jié)束時(shí),必須釋放必須釋放pipi所指向的目標(biāo):所指向的目標(biāo): delete pi;注意這時(shí)釋放了注意這時(shí)釋放了pipi所指的目標(biāo)的內(nèi)存空間,也就是撤銷(xiāo)了所指的目標(biāo)的內(nèi)存空間,也就是撤銷(xiāo)了該目標(biāo),

17、稱(chēng)動(dòng)態(tài)內(nèi)存釋放(該目標(biāo),稱(chēng)動(dòng)態(tài)內(nèi)存釋放(dynamic memory dynamic memory deallocationdeallocation),但),但指針指針pipi本身并沒(méi)有撤銷(xiāo)本身并沒(méi)有撤銷(xiāo),該指針?biāo)?,該指針?biāo)純?nèi)存空間并未釋放。內(nèi)存空間并未釋放。 7.1.17.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放數(shù)組動(dòng)態(tài)分配格式:數(shù)組動(dòng)態(tài)分配格式:指針變量名指針變量名=new 類(lèi)型名類(lèi)型名下標(biāo)表達(dá)式下標(biāo)表達(dá)式;delete 指向該數(shù)組的指針變量名指向該數(shù)組的指針變量名;說(shuō)明:說(shuō)明:兩式中的兩式中的方括號(hào)方括號(hào)必須配對(duì)使用。必須配對(duì)使用。如果如果delete語(yǔ)句中少了方括

18、號(hào),因編譯器認(rèn)為該指針是指語(yǔ)句中少了方括號(hào),因編譯器認(rèn)為該指針是指向數(shù)組第一個(gè)元素的指針,會(huì)產(chǎn)生向數(shù)組第一個(gè)元素的指針,會(huì)產(chǎn)生回收不徹底回收不徹底的問(wèn)題(的問(wèn)題(只只回收了第一個(gè)元素所占空間回收了第一個(gè)元素所占空間),),加了方括號(hào)后就轉(zhuǎn)化為指加了方括號(hào)后就轉(zhuǎn)化為指向數(shù)組的指針,回收整個(gè)數(shù)組向數(shù)組的指針,回收整個(gè)數(shù)組。 delete 的方括號(hào)中的方括號(hào)中不需要不需要填填數(shù)組元素?cái)?shù)數(shù)組元素?cái)?shù),系統(tǒng)自知。,系統(tǒng)自知。即使寫(xiě)了,編譯器也忽略。即使寫(xiě)了,編譯器也忽略。 請(qǐng)注意請(qǐng)注意“下標(biāo)表達(dá)式下標(biāo)表達(dá)式”不是常量表達(dá)式不是常量表達(dá)式,即它,即它的值不必在編譯時(shí)確定,的值不必在編譯時(shí)確定,可以在運(yùn)行時(shí)確

19、定可以在運(yùn)行時(shí)確定。7.1.17.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放動(dòng)態(tài)分配數(shù)組與動(dòng)態(tài)分配數(shù)組與標(biāo)準(zhǔn)字符串類(lèi)標(biāo)準(zhǔn)字符串類(lèi): 標(biāo)準(zhǔn)字符串類(lèi)標(biāo)準(zhǔn)字符串類(lèi)string就是采用動(dòng)態(tài)建立數(shù)組的方式解決就是采用動(dòng)態(tài)建立數(shù)組的方式解決數(shù)組溢出的問(wèn)題的,例數(shù)組溢出的問(wèn)題的,例7.1所做的動(dòng)態(tài)內(nèi)存分配與釋放,所做的動(dòng)態(tài)內(nèi)存分配與釋放,在在string類(lèi)對(duì)象中都是自動(dòng)完成的,在程序中不需要也不類(lèi)對(duì)象中都是自動(dòng)完成的,在程序中不需要也不允許再顯式地為允許再顯式地為string進(jìn)行動(dòng)態(tài)內(nèi)存的分配與釋放。進(jìn)行動(dòng)態(tài)內(nèi)存的分配與釋放?!纠纠?.1】動(dòng)態(tài)數(shù)組的建立與撤銷(xiāo)】動(dòng)態(tài)數(shù)組的建立與撤銷(xiāo)7.1.

20、17.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放【例【例7.17.1】【例【例7.1】動(dòng)態(tài)數(shù)組的建立與撤銷(xiāo)】動(dòng)態(tài)數(shù)組的建立與撤銷(xiāo)#include #include using namespace std;int main()int n;char *pc;cout請(qǐng)輸入動(dòng)態(tài)數(shù)組的元素個(gè)數(shù)請(qǐng)輸入動(dòng)態(tài)數(shù)組的元素個(gè)數(shù)n; /在運(yùn)行時(shí)確定,可輸入在運(yùn)行時(shí)確定,可輸入25pc=new charn;strcpy(pc, 自由存儲(chǔ)區(qū)內(nèi)存的動(dòng)態(tài)分配自由存儲(chǔ)區(qū)內(nèi)存的動(dòng)態(tài)分配);coutpcendl;delete pc;/釋放釋放pc所指向的所指向的n個(gè)字符的內(nèi)存空間個(gè)字符的內(nèi)存空間return 0

21、;#include using namespace std;void main() int n;cinn;int *p=new intn;int num;cinnum;int j=0;while (num0) pj+=num%2;num/=2;for (int i=j-1;i=0;i-)coutpi; delete p;7.1.17.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放動(dòng)態(tài)分配數(shù)組的特點(diǎn):動(dòng)態(tài)分配數(shù)組的特點(diǎn):1. 變量變量n在編譯時(shí)沒(méi)有確定的值,而是在運(yùn)行中輸入,在編譯時(shí)沒(méi)有確定的值,而是在運(yùn)行中輸入,按運(yùn)行按運(yùn)行時(shí)所需分配空間時(shí)所需分配空間,這一點(diǎn)是動(dòng)態(tài)分配的優(yōu)點(diǎn),可克

22、服數(shù)組,這一點(diǎn)是動(dòng)態(tài)分配的優(yōu)點(diǎn),可克服數(shù)組“大開(kāi)小用大開(kāi)小用”的弊端,在表、排序與查找中的算法,若用的弊端,在表、排序與查找中的算法,若用動(dòng)態(tài)數(shù)組,通用性更佳。動(dòng)態(tài)數(shù)組,通用性更佳。delete pc是將是將n個(gè)字符的空間個(gè)字符的空間釋放,而用釋放,而用delete pc則只釋放了一個(gè)字符的空間;則只釋放了一個(gè)字符的空間;2. 如果有如果有char *pc1,令,令pc1=pc,同樣可用,同樣可用delete pc1 來(lái)釋放該空間。盡管來(lái)釋放該空間。盡管C+不對(duì)數(shù)組作邊界檢查,但不對(duì)數(shù)組作邊界檢查,但在自由在自由 存儲(chǔ)區(qū)存儲(chǔ)區(qū) 空間分配時(shí),對(duì)數(shù)組分配空間大小是紀(jì)錄在案的空間分配時(shí),對(duì)數(shù)組分配空

23、間大小是紀(jì)錄在案的。3. 沒(méi)有初始化式(沒(méi)有初始化式(initializer),),不可對(duì)數(shù)組初始化不可對(duì)數(shù)組初始化。 7.1.17.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放(選讀)(選讀)【例【例7.2】 動(dòng)態(tài)創(chuàng)建和刪除一個(gè)動(dòng)態(tài)創(chuàng)建和刪除一個(gè)m*n個(gè)元素的數(shù)組個(gè)元素的數(shù)組7.1.17.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放【例【例7.27.2】 【例【例7.2】 動(dòng)態(tài)創(chuàng)建和刪除一個(gè)動(dòng)態(tài)創(chuàng)建和刪除一個(gè)m*n個(gè)元素的數(shù)組。采用個(gè)元素的數(shù)組。采用指針數(shù)指針數(shù)組方式組方式來(lái)完成二維數(shù)組的動(dòng)態(tài)創(chuàng)建。來(lái)完成二維數(shù)組的動(dòng)態(tài)創(chuàng)建。(選讀選讀)int m=4,n=6; /

24、行數(shù)與列數(shù)行數(shù)與列數(shù)二維數(shù)組的動(dòng)態(tài)創(chuàng)建:二維數(shù)組的動(dòng)態(tài)創(chuàng)建:int main() double *data; int i,j; data = new double*m; /建立指向組成二維數(shù)組各行的指針數(shù)組建立指向組成二維數(shù)組各行的指針數(shù)組 if (data ) = 0) cout Could not allocate. Bye .; return -1; for(j=0;jm;j+) dataj = new doublen; /建立各行建立各行 if (dataj = 0) cout Could not allocate. Bye .; return -1; 7.1.17.1.1自由存儲(chǔ)區(qū)自

25、由存儲(chǔ)區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放【例【例7.27.2】 for (i=0;im;i+) for (j=0;jn;j+) dataij=i*n+j; /數(shù)組元素賦值數(shù)組元素賦值 display(data);/略略 de_allocate(data); return 0; 二維數(shù)組的撤銷(xiāo)與內(nèi)存釋放:二維數(shù)組的撤銷(xiāo)與內(nèi)存釋放:void de_allocate(double *data) int i; for (i=0;im;i+) delete datai; /注意撤銷(xiāo)次序,與設(shè)置相反注意撤銷(xiāo)次序,與設(shè)置相反 delete data; 7.1.17.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)的分配與釋放的分

26、配與釋放指針使用的要點(diǎn):指針使用的要點(diǎn):1. 動(dòng)態(tài)分配失敗動(dòng)態(tài)分配失敗。返回一個(gè)空指針(。返回一個(gè)空指針(NULL),表示發(fā)生了異),表示發(fā)生了異常,堆資源不足,分配失敗。常,堆資源不足,分配失敗。2. 指針刪除與自由存儲(chǔ)區(qū)空間釋放指針刪除與自由存儲(chǔ)區(qū)空間釋放。刪除一個(gè)指針。刪除一個(gè)指針p(delete p;)實(shí)際意思是刪除了)實(shí)際意思是刪除了p所指的目標(biāo)(變量或?qū)ο蟮龋?,釋所指的目?biāo)(變量或?qū)ο蟮龋尫帕怂嫉淖杂纱鎯?chǔ)區(qū)空間,而不是刪除本身,釋放自放了它所占的自由存儲(chǔ)區(qū)空間,而不是刪除本身,釋放自由存儲(chǔ)區(qū)空間后,成了空懸指針??諔抑羔樖浅绦蝈e(cuò)誤的由存儲(chǔ)區(qū)空間后,成了空懸指針??諔抑羔樖浅?/p>

27、序錯(cuò)誤的一個(gè)根源)。建議這時(shí)將置空(一個(gè)根源)。建議這時(shí)將置空(NULL)。)。3. new()和和delete()是可以重載的是可以重載的,它們都是類(lèi)的靜態(tài)成員函,它們都是類(lèi)的靜態(tài)成員函數(shù)。程序員無(wú)需顯式聲明它為靜態(tài)的,系統(tǒng)自動(dòng)定義為靜態(tài)數(shù)。程序員無(wú)需顯式聲明它為靜態(tài)的,系統(tǒng)自動(dòng)定義為靜態(tài)的。本教材不討論的。本教材不討論new()和和delete()的重載。未重載時(shí),調(diào)用的重載。未重載時(shí),調(diào)用全局庫(kù)操作符全局庫(kù)操作符new()。7.1.17.1.1自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存的分配與釋放內(nèi)存的分配與釋放4內(nèi)存泄漏(內(nèi)存泄漏(memory leak)和重復(fù)釋放)和重復(fù)釋放。new與與delete

28、是配對(duì)使用的,是配對(duì)使用的, delete只能釋放只能釋放自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)空間??臻g。如果如果new返回的指針值丟失,則所分配的返回的指針值丟失,則所分配的自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)空間空間無(wú)法回收,稱(chēng)內(nèi)存泄漏,同一空間重復(fù)釋放也是危險(xiǎn)的,無(wú)法回收,稱(chēng)內(nèi)存泄漏,同一空間重復(fù)釋放也是危險(xiǎn)的,因?yàn)橐驗(yàn)樵摽臻g可能已另分配該空間可能已另分配,所以必須妥善保存,所以必須妥善保存new返回的返回的指針,以保證不發(fā)生內(nèi)存泄漏,也必須保證不會(huì)重復(fù)釋放指針,以保證不發(fā)生內(nèi)存泄漏,也必須保證不會(huì)重復(fù)釋放自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)內(nèi)存空間。內(nèi)存空間。5動(dòng)態(tài)分配的變量或?qū)ο蟮纳趧?dòng)態(tài)分配的變量或?qū)ο蟮纳凇o(wú)名對(duì)象的生命

29、期無(wú)名對(duì)象的生命期并不依賴(lài)于建立它的作用域,比如在函數(shù)中建立的動(dòng)態(tài)對(duì)并不依賴(lài)于建立它的作用域,比如在函數(shù)中建立的動(dòng)態(tài)對(duì)象在函數(shù)返回后仍可使用象在函數(shù)返回后仍可使用。但必須記住釋放該對(duì)象所占自。但必須記住釋放該對(duì)象所占自由存儲(chǔ)區(qū)空間,并只能釋放一次,在函數(shù)內(nèi)建立,而在函由存儲(chǔ)區(qū)空間,并只能釋放一次,在函數(shù)內(nèi)建立,而在函數(shù)外釋放是一件很容易數(shù)外釋放是一件很容易失控失控的事,往往會(huì)出錯(cuò)。的事,往往會(huì)出錯(cuò)。 7.1.27.1.2自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)對(duì)象與構(gòu)造函數(shù)對(duì)象與構(gòu)造函數(shù) 類(lèi)對(duì)象動(dòng)態(tài)建立與刪除過(guò)程:類(lèi)對(duì)象動(dòng)態(tài)建立與刪除過(guò)程:通過(guò)通過(guò)new建立的對(duì)象要調(diào)用構(gòu)造函數(shù),通過(guò)建立的對(duì)象要調(diào)用構(gòu)造函數(shù),通過(guò)

30、delete刪除對(duì)刪除對(duì)象也要調(diào)用析構(gòu)函數(shù)。象也要調(diào)用析構(gòu)函數(shù)。CGoods *pc;pc=new CGoods; /分配自由存儲(chǔ)區(qū)空間,并構(gòu)造一個(gè)無(wú)名的分配自由存儲(chǔ)區(qū)空間,并構(gòu)造一個(gè)無(wú)名的CGoods對(duì)象;對(duì)象;.delete pc; /先析構(gòu),然后將內(nèi)存空間返回給自由存儲(chǔ)區(qū);先析構(gòu),然后將內(nèi)存空間返回給自由存儲(chǔ)區(qū);自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)對(duì)象的生命期并不依賴(lài)于建立它的作用域,所以對(duì)象的生命期并不依賴(lài)于建立它的作用域,所以除非程序結(jié)束,除非程序結(jié)束,自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)對(duì)象(無(wú)名對(duì)象)的生命期不會(huì)對(duì)象(無(wú)名對(duì)象)的生命期不會(huì)到期,并且需要顯式地用到期,并且需要顯式地用delete語(yǔ)句析構(gòu)該類(lèi)對(duì)象

31、,上例執(zhí)語(yǔ)句析構(gòu)該類(lèi)對(duì)象,上例執(zhí)行行delete語(yǔ)句時(shí),語(yǔ)句時(shí),C+自動(dòng)調(diào)用商品類(lèi)的析構(gòu)函數(shù)。自動(dòng)調(diào)用商品類(lèi)的析構(gòu)函數(shù)。7.1.27.1.2自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)對(duì)象與構(gòu)造函數(shù)對(duì)象與構(gòu)造函數(shù)由自由存儲(chǔ)區(qū)創(chuàng)建對(duì)象數(shù)組,只能調(diào)用默認(rèn)由自由存儲(chǔ)區(qū)創(chuàng)建對(duì)象數(shù)組,只能調(diào)用默認(rèn)的構(gòu)造函數(shù),不能調(diào)用其他任何構(gòu)造函數(shù)。如果的構(gòu)造函數(shù),不能調(diào)用其他任何構(gòu)造函數(shù)。如果沒(méi)有默認(rèn)的構(gòu)造函數(shù),則不能創(chuàng)建對(duì)象數(shù)組。沒(méi)有默認(rèn)的構(gòu)造函數(shù),則不能創(chuàng)建對(duì)象數(shù)組。類(lèi)對(duì)象初始化:類(lèi)對(duì)象初始化:new后面類(lèi)(后面類(lèi)(class)類(lèi)型可以有參數(shù)。這些參數(shù)即構(gòu)造函數(shù)的)類(lèi)型可以有參數(shù)。這些參數(shù)即構(gòu)造函數(shù)的參數(shù)。但對(duì)參數(shù)。但對(duì)創(chuàng)建數(shù)組創(chuàng)建數(shù)組

32、,則無(wú)參數(shù),則無(wú)參數(shù),只能調(diào)用默認(rèn)的構(gòu)造函數(shù)只能調(diào)用默認(rèn)的構(gòu)造函數(shù)。動(dòng)態(tài)創(chuàng)建對(duì)象舉例動(dòng)態(tài)創(chuàng)建對(duì)象舉例#includeusing namespace std;class Point public: Point() X=Y=0; coutDefault Constructor called.n; Point(int xx,int yy) X=xx; Y=yy; cout Constructor called.n; Point() coutDestructor called.n; int GetX() return X; int GetY() return Y;void Move(int x,int

33、 y) X=x; Y=y; private: int X,Y;int main() coutStep One:endl; Point *Ptr1=new Point; delete Ptr1; coutStep Two:endl; Ptr1=new Point(1,2); delete Ptr1; return 0;運(yùn)行結(jié)果:運(yùn)行結(jié)果:Step One:Step One:Default Constructor called.Default Constructor called.Destructor called.Destructor called.Step Two:Step Two:Const

34、ructor called.Constructor called.Destructor called.Destructor called.7.1.27.1.2自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)對(duì)象與構(gòu)造函數(shù)【例對(duì)象與構(gòu)造函數(shù)【例7.3】類(lèi)說(shuō)明:類(lèi)說(shuō)明:class CGoods string Name; int Amount; float Price; float Total_value;public: CGoods()cout調(diào)用默認(rèn)構(gòu)造函數(shù)調(diào)用默認(rèn)構(gòu)造函數(shù)endl; CGoods(string name,int amount ,float price)cout調(diào)用三參數(shù)構(gòu)造函數(shù)調(diào)用三參數(shù)構(gòu)造函數(shù)endl;

35、Name=name; Amount=amount;Price=price; Total_value=price*amount; CGoods() cout調(diào)用析構(gòu)函數(shù)調(diào)用析構(gòu)函數(shù)endl;【例【例7.37.3】演示自由存儲(chǔ)區(qū)對(duì)象分配和釋放?!垦菔咀杂纱鎯?chǔ)區(qū)對(duì)象分配和釋放。7.1.27.1.2自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)對(duì)象與構(gòu)造函數(shù)【例對(duì)象與構(gòu)造函數(shù)【例7.3】使用:使用:int main() int n; CGoods *pc,*pc1,*pc2; pc=new CGoods(“夏利夏利2000”,10,118000); /調(diào)用三參數(shù)構(gòu)造函數(shù)調(diào)用三參數(shù)構(gòu)造函數(shù) pc1=new CGoods(); /

36、調(diào)用默認(rèn)構(gòu)造函數(shù)調(diào)用默認(rèn)構(gòu)造函數(shù) cout輸入商品類(lèi)數(shù)組元素?cái)?shù)輸入商品類(lèi)數(shù)組元素?cái)?shù)n; pc2=new CGoodsn; /動(dòng)態(tài)建立數(shù)組,不能初始化,調(diào)用動(dòng)態(tài)建立數(shù)組,不能初始化,調(diào)用n次默認(rèn)構(gòu)造函數(shù)次默認(rèn)構(gòu)造函數(shù) delete pc; delete pc1; delete pc2; return 0;7.1.3淺復(fù)制與深復(fù)制淺復(fù)制與深復(fù)制 淺復(fù)制:淺復(fù)制:默認(rèn)復(fù)制構(gòu)造函數(shù)默認(rèn)復(fù)制構(gòu)造函數(shù),可用一個(gè)類(lèi)對(duì)象,可用一個(gè)類(lèi)對(duì)象初始化另一個(gè)類(lèi)對(duì)象,稱(chēng)為默認(rèn)的初始化另一個(gè)類(lèi)對(duì)象,稱(chēng)為默認(rèn)的按成員復(fù)制,按成員復(fù)制,而不是而不是對(duì)整個(gè)類(lèi)對(duì)象的對(duì)整個(gè)類(lèi)對(duì)象的按位復(fù)制。按位復(fù)制。這稱(chēng)為這稱(chēng)為淺復(fù)制。淺復(fù)制。 圖

37、圖7.1 淺復(fù)制淺復(fù)制 P自 由 存自 由 存儲(chǔ) 區(qū) 對(duì)儲(chǔ) 區(qū) 對(duì)象象自 由 存自 由 存儲(chǔ) 區(qū)儲(chǔ) 區(qū) 對(duì)對(duì)象象PP 復(fù)制前復(fù)制前復(fù)制后復(fù)制后 如果類(lèi)中有一個(gè)數(shù)據(jù)成員為指針,該類(lèi)的一個(gè)對(duì)象如果類(lèi)中有一個(gè)數(shù)據(jù)成員為指針,該類(lèi)的一個(gè)對(duì)象obj1中中的這個(gè)指針的這個(gè)指針p,指向了動(dòng)態(tài)分配的一個(gè)自由存儲(chǔ)區(qū)對(duì)象,(參見(jiàn),指向了動(dòng)態(tài)分配的一個(gè)自由存儲(chǔ)區(qū)對(duì)象,(參見(jiàn)圖圖7.1復(fù)制前),如果用復(fù)制前),如果用obj1按成員復(fù)制了一個(gè)對(duì)象按成員復(fù)制了一個(gè)對(duì)象obj2,這時(shí),這時(shí)obj2.p也指向同一個(gè)自由存儲(chǔ)區(qū)對(duì)象。也指向同一個(gè)自由存儲(chǔ)區(qū)對(duì)象。obj1obj1obj27.1.3淺復(fù)制與深復(fù)制復(fù)制淺復(fù)制與深復(fù)制復(fù)

38、制當(dāng)當(dāng)淺復(fù)制淺復(fù)制析構(gòu)時(shí),如用默認(rèn)的析構(gòu)析構(gòu)時(shí),如用默認(rèn)的析構(gòu)函數(shù),則動(dòng)態(tài)分配的函數(shù),則動(dòng)態(tài)分配的自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)對(duì)象不對(duì)象不能回收。如果在析構(gòu)函數(shù)中有能回收。如果在析構(gòu)函數(shù)中有“delete p;”語(yǔ)句,則如果先析構(gòu)函數(shù)語(yǔ)句,則如果先析構(gòu)函數(shù)obj1時(shí),時(shí),自由存儲(chǔ)區(qū)自由存儲(chǔ)區(qū)對(duì)象已經(jīng)釋放,以后再析構(gòu)對(duì)象已經(jīng)釋放,以后再析構(gòu)obj2時(shí)出現(xiàn)了二次釋放的問(wèn)題。時(shí)出現(xiàn)了二次釋放的問(wèn)題。自由自由存儲(chǔ)存儲(chǔ)區(qū)區(qū)對(duì)對(duì)象象PP自由自由存儲(chǔ)存儲(chǔ)區(qū)區(qū)對(duì)對(duì)象象 圖圖7.2 深復(fù)制深復(fù)制 深復(fù)制:深復(fù)制:重新定義復(fù)制的構(gòu)造函數(shù),重新定義復(fù)制的構(gòu)造函數(shù),給每個(gè)對(duì)象獨(dú)立分配一個(gè)自由存儲(chǔ)區(qū)給每個(gè)對(duì)象獨(dú)立分配一個(gè)自由存

39、儲(chǔ)區(qū)對(duì)象,稱(chēng)對(duì)象,稱(chēng)深復(fù)制深復(fù)制。這時(shí)先復(fù)制對(duì)象主這時(shí)先復(fù)制對(duì)象主體,再為體,再為obj2分配一個(gè)自由存儲(chǔ)區(qū)對(duì)分配一個(gè)自由存儲(chǔ)區(qū)對(duì)象,最后用象,最后用obj1的自由存儲(chǔ)區(qū)對(duì)象復(fù)的自由存儲(chǔ)區(qū)對(duì)象復(fù)制制obj2的自由存儲(chǔ)區(qū)對(duì)象。的自由存儲(chǔ)區(qū)對(duì)象。 obj1obj27.1.3淺復(fù)制與深復(fù)制淺復(fù)制與深復(fù)制【例【例7.4】定義復(fù)制構(gòu)造函數(shù)定義復(fù)制構(gòu)造函數(shù) (copy structor)和復(fù)制賦值操)和復(fù)制賦值操作符(作符(copy Assignment Operator)實(shí)現(xiàn)深復(fù)制。)實(shí)現(xiàn)深復(fù)制。 學(xué)生類(lèi)定義:學(xué)生類(lèi)定義:class student char *pName; /為了演示深復(fù)制,不用為了演

40、示深復(fù)制,不用string類(lèi)類(lèi)public: student(); /默認(rèn)構(gòu)造函數(shù)默認(rèn)構(gòu)造函數(shù) student(char *pname); /帶參數(shù)構(gòu)造函數(shù)帶參數(shù)構(gòu)造函數(shù) student(student &s); /復(fù)制構(gòu)造函數(shù)復(fù)制構(gòu)造函數(shù) student(); /析構(gòu)函數(shù)析構(gòu)函數(shù) student & operator=(student &s); ; /復(fù)制賦值操作符復(fù)制賦值操作符檢驗(yàn)主函數(shù)和運(yùn)行結(jié)果檢驗(yàn)主函數(shù)和運(yùn)行結(jié)果例例7.4 實(shí)現(xiàn)深復(fù)制實(shí)現(xiàn)深復(fù)制默認(rèn)構(gòu)造函數(shù):默認(rèn)構(gòu)造函數(shù):student:student() coutConstructor; pName=NULL;

41、 cout默認(rèn)默認(rèn)“endl;帶參數(shù)構(gòu)造函數(shù):帶參數(shù)構(gòu)造函數(shù):student:student(char *pname) coutConstructor; if(pName=new charstrlen(pname)+1) strcpy(pName,pname); coutpNameendl;例例7.4 實(shí)現(xiàn)深復(fù)制實(shí)現(xiàn)深復(fù)制復(fù)制構(gòu)造函數(shù):復(fù)制構(gòu)造函數(shù):student:student(student &s) coutCopy Constructor; if(s.pName) if(pName=new charstrlen(s.pName)+1) strcpy(pName,s.pName); else pName=NULL; coutpNameendl;析構(gòu)函數(shù):析構(gòu)函數(shù):student:student() coutDestructorpNameendl; if(pName) pName0=0; delete pName; /釋放字符串釋放字符串例例7.4 實(shí)現(xiàn)深復(fù)制實(shí)現(xiàn)深復(fù)制復(fù)制賦值操作符:復(fù)制賦值操作符:student & student:operator=(student &s) coutCopy Assign operator; delete pName;/如原來(lái)已分配,應(yīng)先撤銷(xiāo),再重分配如原來(lái)已分配,

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 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ì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論