一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

一文讀懂C語(yǔ)言與C++動(dòng)態(tài)內(nèi)存

 C語(yǔ)言與CPP編程 2021-12-15

程序在編譯、運(yùn)行等各個(gè)過(guò)程中,不同性質(zhì)的數(shù)據(jù)存放在不同的位置。動(dòng)態(tài)內(nèi)存是從堆上分配,也叫動(dòng)態(tài)內(nèi)存分配。程序員自己負(fù)責(zé)在何時(shí)釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活。

C、C++程序編譯的內(nèi)存分配

1.從靜態(tài)存儲(chǔ)區(qū)域分配

內(nèi)存在程序編譯時(shí)就已經(jīng)分配好,這塊內(nèi)存在程序的整個(gè)運(yùn)行期間都存在。速度快、不容易出錯(cuò),因?yàn)橛邢到y(tǒng)會(huì)善后。例如全局變量,static變量等。

2.在棧上分配

在執(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申請(qǐng)任意大小的內(nèi)存,程序員自己負(fù)責(zé)在何時(shí)用free或delete釋放內(nèi)存。動(dòng)態(tài)內(nèi)存的生存期由程序員決定,使用非常靈活。如果在堆上分配了空間,就有責(zé)任回收它,否則運(yùn)行的程序會(huì)出現(xiàn)內(nèi)存泄漏,另外頻繁地分配和釋放不同大小的堆空間將會(huì)產(chǎn)生堆內(nèi)碎塊。

一個(gè)C、C++程序編譯時(shí)內(nèi)存分為5大存儲(chǔ)區(qū):堆區(qū)、棧區(qū)、全局區(qū)、文字常量區(qū)、程序代碼區(qū),如下表所示。

C、C++的程序編譯時(shí)內(nèi)存分配情況

實(shí)例:

int a=0; //全局區(qū)初始化a
char *p1; //全局區(qū)未初始化p1
static char b; //全局區(qū)未初始化靜態(tài)變量b

int main(void)
{
int c; //棧區(qū)臨時(shí)變量c
char s[]="abc"; //棧區(qū)臨時(shí)數(shù)組變量s
char *p2; //棧區(qū)臨時(shí)變量p2
char *p3="123"; //常量區(qū)常量123,棧區(qū)指針變量p3
static int d=0; //全局靜態(tài)初始化靜態(tài)變量d
p1=new char[10]; //堆區(qū)分配10個(gè)字節(jié)符空間
p2=new char[20]; //堆區(qū)分配20個(gè)字節(jié)符空間
strcpy(p1,"123); //123放在常量區(qū),編譯器可能會(huì)將它與p3所指向的"123"優(yōu)化成一個(gè)地方
}

答案

  • 棧區(qū)(stack):由編譯器自動(dòng)分配釋放,存放為運(yùn)行函數(shù)而分配的局部變量、函數(shù)參數(shù)、返回?cái)?shù)據(jù)、返回地址等。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
  • 堆區(qū)(heap):一般由程序員分配釋放,若程序員不釋放,程序結(jié)束時(shí)可能由系統(tǒng)回收。分配方式類似于鏈表。
  • 全局區(qū)(靜態(tài)區(qū))(static):存放全局變量、靜態(tài)數(shù)據(jù)、常量。程序結(jié)束后由系統(tǒng)釋放。
  • 文字常量區(qū):常量字符串就是放在這里的。程序結(jié)束后由系統(tǒng)釋放。
  • (5)程序代碼區(qū):存放函數(shù)體(類成員函數(shù)和全局函數(shù))的二進(jìn)制代碼。

補(bǔ)充:在不同的內(nèi)存區(qū)域,對(duì)于理解編程中的數(shù)據(jù)類型作用域和注意事項(xiàng),比如靜態(tài)數(shù)據(jù)和全局?jǐn)?shù)據(jù)對(duì)其聲明后區(qū)域的全局可見性,動(dòng)態(tài)申請(qǐng)的內(nèi)存為什么要及時(shí)釋放等有很大的幫助。

2 分析代碼段有沒有錯(cuò)誤

代碼段1

void A(char *p)
{
p=(char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
A(str);
strcpy(str,"hello world";
printf(str);
}

代碼段2

char *A(void)
{
char p[]="hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = A();
printf(str);
}

代碼段3

void A(char **p,int num)
{
*p=(char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
A(&str,100);
strcpy(str,"hello");
printf(str);
}

代碼段4

void Test(void)
{
char *str = (char *)malloc(100);
strcpy(str,"hello";
free(str);
}

分析問題:代碼一到代碼四主要考查面試者對(duì)內(nèi)存操作的理解程度,基本功扎實(shí)的面試者能找到大部分的錯(cuò)誤,但是全部找出還是有一定難度的。這四段代碼主要有以下三個(gè)問題:

  1. 指針的理解和使用問題。
  2. 變量生存周期和作用域的問題。
  3. 動(dòng)態(tài)內(nèi)存申請(qǐng)和釋放的問題。

代碼一:傳入函數(shù)A( char *p )的參數(shù)為字符型指針,在這個(gè)函數(shù)修改參數(shù)p的值時(shí)并不能真正修改實(shí)參的值,如:

char *str = NULL;
A(str);

執(zhí)行完這兩句后str的值仍然是NULL,如果想改變指針的值,就得用二階指針來(lái)完成。不理解指針和指針的用法是導(dǎo)致這個(gè)錯(cuò)誤的主要原因。

代碼二:在函數(shù)A(void )中:

char p[]="hello world";
return p;

其中的p[]數(shù)組是函數(shù)A中的局部變量,函數(shù)返回后,p就被釋放掉了,str指向了一段無(wú)用的內(nèi)存區(qū)域,輸出的str會(huì)是亂碼。理解變量的作用域是解決本題的關(guān)鍵。

代碼三:避免了代碼一中的問題,A的參數(shù)是二階指針,傳入的參數(shù)也是字符串的指針的指針,這樣就可以在函數(shù)A中改變字符串指針的值了。但是在A中執(zhí)行了申請(qǐng)動(dòng)態(tài)內(nèi)存的并且賦值給字符串指針的語(yǔ)句:

*p=(char *)malloc(num);

在Test中A返回后,沒有對(duì)指針*p做任何判斷就使用了p。

strcpy(str,"hello");

假如動(dòng)態(tài)內(nèi)存沒有申請(qǐng)成功,這句就會(huì)出現(xiàn)錯(cuò)誤,所以在申請(qǐng)動(dòng)態(tài)內(nèi)存后,應(yīng)該首先判斷是內(nèi)存否申請(qǐng)成功,然后再使用,以避免錯(cuò)誤發(fā)生。如下:

if(*p =NULL)
{
.......//申請(qǐng)失敗異常處理
}

另外,沒有釋放動(dòng)態(tài)申請(qǐng)的內(nèi)存空間。

代碼四:同代碼三一樣,申請(qǐng)了動(dòng)態(tài)內(nèi)存后沒有檢驗(yàn)是否申請(qǐng)成功就直接使用,并且在free( str)后str沒有置空,str成了“野指針”。一定要記得每次釋放動(dòng)態(tài)申請(qǐng)的內(nèi)存空間后指針要置空,如下:

free(str);
str = NULL;

答案

四段代碼全有錯(cuò)誤:

  • 代碼一:A( char *p )的參數(shù)為字符型指針,在這個(gè)函數(shù)修改參數(shù)p的值時(shí)并不能真正修改實(shí)參的值。
  • 代碼二:其中的p[]數(shù)組是函數(shù)A中的局部變量,函數(shù)返回后,p就被釋放掉,str便指向了一段無(wú)用的內(nèi)存區(qū)域。
  • 代碼三:沒有判斷動(dòng)態(tài)內(nèi)存申請(qǐng)是否成功而直接使用,沒有釋放動(dòng)態(tài)申請(qǐng)的內(nèi)存,造成內(nèi)存泄漏。
  • 代碼四:沒有判斷動(dòng)態(tài)內(nèi)存申請(qǐng)是否成功而直接使用,動(dòng)態(tài)內(nèi)存釋放后沒有將指針置空。

注意:申請(qǐng)動(dòng)態(tài)內(nèi)存時(shí)一定要先判斷是否申請(qǐng)成功,失敗時(shí)要進(jìn)行失敗處理;動(dòng)態(tài)內(nèi)存使用后要及時(shí)釋放,不要造成內(nèi)存的泄漏;釋放后將原先指向動(dòng)態(tài)內(nèi)存的指針置空,以免生成“野指針”。

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    国产日韩久久精品一区| 国产精品九九九一区二区| 国产精品涩涩成人一区二区三区 | 日韩高清中文字幕亚洲| 国产欧美日韩在线一区二区| 神马午夜福利一区二区| 亚洲第一视频少妇人妻系列| 亚洲综合伊人五月天中文 | 日韩欧美在线看一卡一卡| 久久本道综合色狠狠五月| 午夜精品麻豆视频91| 九九热这里有精品20| 香蕉尹人视频在线精品| 国产精品免费精品一区二区| 亚洲免费视频中文字幕在线观看 | 色婷婷激情五月天丁香| 国产精品午夜性色视频| 女同伦理国产精品久久久| 国产精品香蕉免费手机视频| 亚洲天堂精品在线视频| 国产免费人成视频尤物| 成人精品一区二区三区综合| 色婷婷在线视频免费播放| 欧美成人一区二区三区在线| 都市激情小说在线一区二区三区| 大胆裸体写真一区二区| 久久大香蕉精品在线观看| 熟女乱一区二区三区丝袜| 欧美一级内射一色桃子| 福利视频一区二区在线| 美女被后入福利在线观看| 高清欧美大片免费在线观看| 91在线国内在线中文字幕| 亚洲黄片在线免费小视频| 日韩国产传媒在线精品| 夫妻激情视频一区二区三区| 精品国产av一区二区三区不卡蜜| 久久精品色妇熟妇丰满人妻91| 精品国产亚洲一区二区三区| 亚洲精品国产精品日韩| 欧美又黑又粗大又硬又爽|