亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 第7章 內存管理.txt

?? 高質量c++_c編程指南習題集(含答案),林銳主編
?? TXT
?? 第 1 頁 / 共 2 頁
字號:
函數Test5運行雖然不會出錯,但是函數GetString2的設計概念卻是錯誤的。因為GetString2內的“hello world”是常量字符串,位于靜態存儲區,它在程序生命期內恒定不變。無論什么時候調用GetString2,它返回的始終是同一個“只讀”的內存塊。


7.5 free和delete把指針怎么啦?
7.7 杜絕“野指針”
“野指針”不是NULL指針,是指向“垃圾”內存的指針。人們一般不會錯用NULL指針,因為用if語句很容易判斷。但是“野指針”是很危險的,if語句對它不起作用。 

“野指針”的成因主要有兩種:

(1)指針變量沒有被初始化。任何指針變量剛被創建時不會自動成為NULL指針,它的缺省值是隨機的,它會亂指一氣。所以,指針變量在創建的同時應當被初始化,要么將指針設置為NULL,要么讓它指向合法的內存。例如

char *p = NULL;

char *str = (char *) malloc(100);


(2)指針p被free或者delete之后,沒有置為NULL,讓人誤以為p是個合法的指針。參見7.5節。


(3)指針操作超越了變量的作用范圍。這種情況讓人防不勝防,示例程序如下:

class A 

{ 

public:

void Func(void){ cout << “Func of class A” << endl; }

};

void Test(void)

{

A *p;

{

A a;

p = &a; // 注意 a 的生命期

}

p->Func(); // p是“野指針”

}


函數Test在執行語句p->Func()時,對象a已經消失,而p是指向a的,所以p就成了“野指針”。但奇怪的是我運行這個程序時居然沒有出錯,這可能與編譯器有關。


7.8 有了malloc/free為什么還要new/delete ?
malloc與free是C++/C語言的標準庫函數,new/delete是C++的運算符。它們都可用于申請動態內存和釋放內存。

對于非內部數據類型的對象而言,光用maloc/free無法滿足動態對象的要求。對象在創建的同時要自動執行構造函數,對象在消亡之前要自動執行析構函數。由于malloc/free是庫函數而不是運算符,不在編譯器控制權限之內,不能夠把執行構造函數和析構函數的任務強加于malloc/free。

因此C++語言需要一個能完成動態內存分配和初始化工作的運算符new,以及一個能完成清理與釋放內存工作的運算符delete。注意new/delete不是庫函數。

我們先看一看malloc/free和new/delete如何實現對象的動態內存管理,見示例7-8。


class Obj

{

public :

Obj(void){ cout << “Initialization” << endl; }

~Obj(void){ cout << “Destroy” << endl; }

void Initialize(void){ cout << “Initialization” << endl; }

void Destroy(void){ cout << “Destroy” << endl; }

};

void UseMallocFree(void)

{

Obj *a = (obj *)malloc(sizeof(obj)); // 申請動態內存

a->Initialize(); // 初始化

//…

a->Destroy(); // 清除工作

free(a); // 釋放內存

}

void UseNewDelete(void)

{

Obj *a = new Obj; // 申請動態內存并且初始化

//…

delete a; // 清除并且釋放內存

}


示例7-8 用malloc/free和new/delete如何實現對象的動態內存管理


類Obj的函數Initialize模擬了構造函數的功能,函數Destroy模擬了析構函數的功能。函數UseMallocFree中,由于malloc/free不能執行構造函數與析構函數,必須調用成員函數Initialize和Destroy來完成初始化與清除工作。函數UseNewDelete則簡單得多。

所以我們不要企圖用malloc/free來完成動態對象的內存管理,應該用new/delete。由于內部數據類型的“對象”沒有構造與析構的過程,對它們而言malloc/free和new/delete是等價的。

既然new/delete的功能完全覆蓋了malloc/free,為什么C++不把malloc/free淘汰出局呢?這是因為C++程序經常要調用C函數,而C程序只能用malloc/free管理動態內存。

如果用free釋放“new創建的動態對象”,那么該對象因無法執行析構函數而可能導致程序出錯。如果用delete釋放“malloc申請的動態內存”,理論上講程序不會出錯,但是該程序的可讀性很差。所以new/delete必須配對使用,malloc/free也一樣。


7.9 內存耗盡怎么辦?
如果在申請動態內存時找不到足夠大的內存塊,malloc和new將返回NULL指針,宣告內存申請失敗。通常有三種方式處理“內存耗盡”問題。

(1)判斷指針是否為NULL,如果是則馬上用return語句終止本函數。例如:

void Func(void)

{

A *a = new A;

if(a == NULL)

{

return;

}


}


(2)判斷指針是否為NULL,如果是則馬上用exit(1)終止整個程序的運行。例如:

void Func(void)

{

A *a = new A;

if(a == NULL)

{

cout << “Memory Exhausted” << endl;

exit(1);

}


}


(3)為new和malloc設置異常處理函數。例如Visual C++可以用_set_new_hander函數為new設置用戶自己定義的異常處理函數,也可以讓malloc享用與new相同的異常處理函數。詳細內容請參考C++使用手冊。


上述(1)(2)方式使用最普遍。如果一個函數內有多處需要申請動態內存,那么方式(1)就顯得力不從心(釋放內存很麻煩),應該用方式(2)來處理。

很多人不忍心用exit(1),問:“不編寫出錯處理程序,讓操作系統自己解決行不行?”

不行。如果發生“內存耗盡”這樣的事情,一般說來應用程序已經無藥可救。如果不用exit(1) 把壞程序殺死,它可能會害死操作系統。道理如同:如果不把歹徒擊斃,歹徒在老死之前會犯下更多的罪。


有一個很重要的現象要告訴大家。對于32位以上的應用程序而言,無論怎樣使用malloc與new,幾乎不可能導致“內存耗盡”。我在Windows 98下用Visual C++編寫了測試程序,見示例7-9。這個程序會無休止地運行下去,根本不會終止。因為32位操作系統支持“虛存”,內存用完了,自動用硬盤空間頂替。我只聽到硬盤嘎吱嘎吱地響,Window 98已經累得對鍵盤、鼠標毫無反應。

我可以得出這么一個結論:對于32位以上的應用程序,“內存耗盡”錯誤處理程序毫無用處。這下可把Unix和Windows程序員們樂壞了:反正錯誤處理程序不起作用,我就不寫了,省了很多麻煩。

我不想誤導讀者,必須強調:不加錯誤處理將導致程序的質量很差,千萬不可因小失大。


void main(void)

{

float *p = NULL;

while(TRUE)

{

p = new float[1000000]; 

cout << “eat memory” << endl;

if(p==NULL)

exit(1);

}

}


示例7-9試圖耗盡操作系統的內存

7.10 malloc/free 的使用要點
函數malloc的原型如下:

void * malloc(size_t size);

用malloc申請一塊長度為length的整數類型的內存,程序如下:

int *p = (int *) malloc(sizeof(int) * length);

我們應當把注意力集中在兩個要素上:“類型轉換”和“sizeof”。

u malloc返回值的類型是void *,所以在調用malloc時要顯式地進行類型轉換,將void * 轉換成所需要的指針類型。

u malloc函數本身并不識別要申請的內存是什么類型,它只關心內存的總字節數。我們通常記不住int, float等數據類型的變量的確切字節數。例如int變量在16位系統下是2個字節,在32位下是4個字節;而float變量在16位系統下是4個字節,在32位下也是4個字節。最好用以下程序作一次測試:

cout << sizeof(char) << endl;

cout << sizeof(int) << endl;

cout << sizeof(unsigned int) << endl;

cout << sizeof(long) << endl;

cout << sizeof(unsigned long) << endl;

cout << sizeof(float) << endl;

cout << sizeof(double) << endl;

cout << sizeof(void *) << endl;


在malloc的“()”中使用sizeof運算符是良好的風格,但要當心有時我們會昏了頭,寫出 p = malloc(sizeof(p))這樣的程序來。


u 函數free的原型如下:

void free( void * memblock );

為什么free函數不象malloc函數那樣復雜呢?這是因為指針p的類型以及它所指的內存的容量事先都是知道的,語句free(p)能正確地釋放內存。如果p是NULL指針,那么free對p無論操作多少次都不會出問題。如果p不是NULL指針,那么free對p連續操作兩次就會導致程序運行錯誤。

7.11 new/delete 的使用要點
運算符new使用起來要比函數malloc簡單得多,例如:

int *p1 = (int *)malloc(sizeof(int) * length);

int *p2 = new int[length];

這是因為new內置了sizeof、類型轉換和類型安全檢查功能。對于非內部數據類型的對象而言,new在創建動態對象的同時完成了初始化工作。如果對象有多個構造函數,那么new的語句也可以有多種形式。例如

class Obj

{

public :

Obj(void); // 無參數的構造函數

Obj(int x); // 帶一個參數的構造函數


}

void Test(void)

{

Obj *a = new Obj;

Obj *b = new Obj(1); // 初值為1


delete a;

delete b;

}

如果用new創建對象數組,那么只能使用對象的無參數構造函數。例如

Obj *objects = new Obj[100]; // 創建100個動態對象

不能寫成

Obj *objects = new Obj[100](1);// 創建100個動態對象的同時賦初值1

在用delete釋放對象數組時,留意不要丟了符號‘[]’。例如

delete []objects; // 正確的用法

delete objects; // 錯誤的用法

后者相當于delete objects[0],漏掉了另外99個對象。

7.12 一些心得體會
我認識不少技術不錯的C++/C程序員,很少有人能拍拍胸脯說通曉指針與內存管理(包括我自己)。我最初學習C語言時特別怕指針,導致我開發第一個應用軟件(約1萬行C代碼)時沒有使用一個指針,全用數組來頂替指針,實在蠢笨得過分。躲避指針不是辦法,后來我改寫了這個軟件,代碼量縮小到原先的一半。

我的經驗教訓是:

(1)越是怕指針,就越要使用指針。不會正確使用指針,肯定算不上是合格的程序員。

(2)必須養成“使用調試器逐步跟蹤程序”的習慣,只有這樣才能發現問題的本質。


?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
一区二区三区在线观看动漫| 欧美日韩一本到| 成人黄色软件下载| 欧美午夜电影在线播放| 国产三级一区二区三区| 日韩国产精品大片| 欧美三级蜜桃2在线观看| 亚洲精品国产高清久久伦理二区| 久久国产视频网| 色综合久久66| 国产精品美女久久久久久久| 在线播放欧美女士性生活| 国产欧美日韩在线| 国产一区中文字幕| 日韩一区二区在线看| 亚洲v中文字幕| 欧美亚洲一区三区| 亚洲精品国产第一综合99久久| 成人看片黄a免费看在线| 欧美电视剧在线观看完整版| 日韩av一区二区三区四区| 欧美日韩综合在线免费观看| 亚洲综合一区二区| 欧美主播一区二区三区美女| 亚洲男同1069视频| 91久久一区二区| 亚洲三级在线免费| 91偷拍与自偷拍精品| ㊣最新国产の精品bt伙计久久| 国产成人精品一区二区三区四区| 国产丝袜在线精品| 成人激情图片网| 中文字幕一区二区在线播放| 久久久国际精品| 欧洲精品中文字幕| 一区二区国产视频| 欧美性生活一区| 五月婷婷综合激情| 日韩欧美在线观看一区二区三区| 亚洲v精品v日韩v欧美v专区 | 亚洲成人综合在线| 欧美视频一区二区| 欧美a级一区二区| 精品乱人伦一区二区三区| 99在线精品观看| 国产精品盗摄一区二区三区| 91免费看`日韩一区二区| 亚洲国产裸拍裸体视频在线观看乱了| 欧美三级欧美一级| 激情成人午夜视频| 国产精品久久久久婷婷| 色久综合一二码| 天堂蜜桃91精品| 久久久久久99久久久精品网站| 国产成a人亚洲| 亚洲自拍偷拍av| 精品国产区一区| 成人av在线播放网址| 亚洲国产视频直播| 久久亚洲二区三区| 在线观看一区二区视频| 免费高清在线一区| 中文字幕一区二区日韩精品绯色| 欧美日韩成人一区| 久久www免费人成看片高清| 国产精品伦一区二区三级视频| 欧美午夜宅男影院| 国产黄色91视频| 亚洲电影一区二区| 国产日韩欧美a| 欧美日韩一级二级三级| 国产99久久久国产精品免费看 | 亚洲女厕所小便bbb| 欧美成人bangbros| 色婷婷综合久久久久中文一区二区 | 韩国一区二区三区| 亚洲一二三专区| 中文字幕不卡的av| 日韩一级免费观看| 在线观看视频一区二区| 成人综合激情网| 免费精品视频在线| 一区二区高清视频在线观看| 久久精品夜夜夜夜久久| 日韩视频一区在线观看| 色婷婷av一区二区三区之一色屋| 久久99国产精品久久| 亚洲成人久久影院| 精品视频1区2区3区| 成人激情av网| 秋霞电影一区二区| 亚洲欧美日韩国产手机在线| 久久精品一区二区三区av| 欧美电影一区二区三区| 99re66热这里只有精品3直播 | 青青青伊人色综合久久| 依依成人综合视频| 亚洲三级电影网站| 国产精品区一区二区三| 久久久久99精品国产片| 日韩三级精品电影久久久| 欧美三级蜜桃2在线观看| 色呦呦日韩精品| 91麻豆123| 色综合天天综合网天天看片| 丁香五精品蜜臀久久久久99网站 | 日韩国产在线观看一区| 亚洲高清免费一级二级三级| 亚洲在线观看免费视频| 一区二区三区免费在线观看| 亚洲人成精品久久久久久| 国产精品二三区| 国产精品九色蝌蚪自拍| 亚洲国产精品t66y| 国产精品色婷婷| 最新成人av在线| 亚洲人成精品久久久久| 一区二区三区四区视频精品免费 | 91黄视频在线观看| 欧美亚洲国产一区二区三区va| 91女人视频在线观看| 91在线观看免费视频| 欧美亚洲国产一卡| 欧美群妇大交群中文字幕| 7777精品伊人久久久大香线蕉超级流畅 | 日韩毛片视频在线看| 亚洲免费观看高清| 亚洲线精品一区二区三区 | 波多野结衣91| 一本大道久久a久久精二百| 欧美在线影院一区二区| 欧美日韩国产一二三| 日韩欧美亚洲国产另类| 久久久精品免费免费| 亚洲欧洲国产专区| 婷婷成人激情在线网| 九色porny丨国产精品| 福利电影一区二区| 欧美综合天天夜夜久久| 91精品国产综合久久久久| 精品99999| 日本一二三四高清不卡| 久久久综合网站| 日韩精品一区国产麻豆| 国产日韩av一区| 亚洲精品国产第一综合99久久 | 88在线观看91蜜桃国自产| 日韩欧美国产精品| 国产精品久久久久久久久久免费看| 成人欧美一区二区三区白人| 亚洲国产中文字幕在线视频综合| 日韩国产精品91| 成人av集中营| 制服丝袜亚洲播放| 国产精品国产三级国产| 亚洲国产一区二区a毛片| 国产精品综合一区二区| 欧美日韩在线精品一区二区三区激情| 日韩欧美www| 亚洲综合在线视频| 国产成人av在线影院| 欧美精品vⅰdeose4hd| 欧美激情一区二区三区不卡| 国产蜜臀97一区二区三区| 亚洲免费在线观看视频| 国内精品免费**视频| 欧美色爱综合网| 中文字幕巨乱亚洲| 免费成人你懂的| 精品1区2区3区| 成人欧美一区二区三区| 国产风韵犹存在线视精品| 欧美日韩一区二区三区在线看| 国产精品视频看| 国产精品69久久久久水密桃| 欧美一级二级三级蜜桃| 亚洲色欲色欲www| 成人性色生活片| 欧美电视剧在线看免费| 日韩电影一区二区三区四区| 欧美亚洲国产一区在线观看网站| 国产精品高清亚洲| 高清日韩电视剧大全免费| 久久综合精品国产一区二区三区| 日韩vs国产vs欧美| 欧美三级电影一区| 亚洲最新视频在线观看| 99精品黄色片免费大全| 中文字幕制服丝袜一区二区三区| 国产综合一区二区| 精品国产伦一区二区三区观看体验| 亚洲综合视频在线| 在线视频欧美区| 亚洲最大成人网4388xx| 色婷婷av一区| 亚洲成人777| 欧美一区二区三区免费大片| 日本不卡不码高清免费观看| 欧美一区午夜视频在线观看| 蜜臀av性久久久久av蜜臀妖精 |