C基礎(chǔ)-內(nèi)存的四驅(qū)模型

數(shù)據(jù)類型的本質(zhì)

數(shù)據(jù)類型本質(zhì):一個(gè)固定大小連續(xù)的內(nèi)存塊。
數(shù)據(jù)類型的作用:分配內(nèi)存空間大小

變量的本質(zhì)

變量的本質(zhì):一段連續(xù)內(nèi)存空間的別名

程序運(yùn)行流程

1.操作系統(tǒng)把物理硬盤的代碼 load到內(nèi)存中(運(yùn)行的是 .exe文件)
2.操作系統(tǒng)把C 代碼分成四個(gè)區(qū)
3.操作系統(tǒng)找到main 函數(shù)的執(zhí)行入口

內(nèi)存四驅(qū)模型

在 c/c++ 中我們將運(yùn)行時(shí)數(shù)據(jù),分為四個(gè)區(qū)域分別是:棧區(qū),堆區(qū),數(shù)據(jù)區(qū),代碼區(qū):
1.棧區(qū):存放函數(shù)的參數(shù)值,局部變量的值等,由編譯器自動(dòng)分配釋放。
2.堆區(qū):存放的是一般我們自己malloc()或者new 出來的對(duì)象,一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由 OS 回收。malloc對(duì)應(yīng)free,new 對(duì)應(yīng) delete
3.數(shù)據(jù)區(qū)(靜態(tài)區(qū)/全局區(qū)):存放全局變量、靜態(tài)變量和常量字符串等等。 程序結(jié)束后由系統(tǒng)釋放
4.存放函數(shù)體的二進(jìn)制代碼。

*1. 棧區(qū)
void change2(int * a){
    *a = 200;
}
void change1(int a){
    a = 200;
}

void main(){
    int  a = 100;
    int b = 10;
    change1(b);
    change2(&a);
    printf("change1 =%d,change2=%d", b,a);
    getchar();
}

//結(jié)果:change1 =10,change2=200

從結(jié)果上發(fā)現(xiàn)changge1()這個(gè)方法并沒有改變b的值,而change2 () 改變了。

當(dāng)執(zhí)行 到 int a = 100; int b = 10時(shí) 棧區(qū)的結(jié)構(gòu)時(shí)這樣的


image.png

當(dāng)執(zhí)行到change1(b)函數(shù)體內(nèi)的時(shí)候,只是把變量a的值給了change1()函數(shù)的a.當(dāng)該函數(shù)體執(zhí)行完后,因?yàn)闂^(qū)時(shí)會(huì)自己回收的所以change1()的內(nèi)存數(shù)據(jù)是會(huì)被清空的。所以b的值沒有改變 b=10。
當(dāng)執(zhí)行到change2(&a);函數(shù)體內(nèi)的時(shí)候,因?yàn)槭莻鬟f的是a地址,然后通過地址修改a 的值,當(dāng)
change2(&a)執(zhí)行完 內(nèi)存被清空后,a 的值已經(jīng)發(fā)生改變了。


image.png
*2. 全局區(qū)
char * getStr1(){
    char *p1 = "aaaaa";
    return p1;
}

char *getStr2(){
    char *p2 = "aaaaa";
    return p2;
}

void main(){
    char *p1 = NULL;
    char *p2 = NULL;

    p1 = getStr1();
    p2 = getStr2();

    printf("p1:%s , p2:%s \n", p1, p2);
    printf("p1:%d , p2:%d \n", p1, p2);

    getchar();

    // 打印結(jié)果:p1:aaaaa , p2:aaaaa  p1:10181068, p2 : 10181068
}

從打印結(jié)果可以看出p1 和p2 地址相同,指向的內(nèi)容也相同
函數(shù)從main()函數(shù)入口執(zhí)行,

 char *p1 = NULL;
 char *p2 = NULL;

對(duì)應(yīng)的四驅(qū)模型如圖:

編譯器分別將變量p1,p2在棧區(qū)壓棧,并給定初始值為NULL。
當(dāng)執(zhí)行g(shù)etStr1()到函數(shù)體時(shí)如圖:

當(dāng)執(zhí)行 p1 = getStr1()函數(shù)返回值賦給p1的時(shí)候,編譯器會(huì)將getstr()函數(shù)在運(yùn)行期其間申請(qǐng)的所有的棧區(qū)內(nèi)存進(jìn)行釋放。內(nèi)存四區(qū)如下:

同一樣,當(dāng)執(zhí)行p2 = getStr2();語句時(shí)基本的內(nèi)變化和p1相同,唯一不同的是編譯器會(huì)對(duì)我我們的代碼進(jìn)行優(yōu)化,p2指向的內(nèi)存的值和p1相同時(shí),編譯器會(huì)只保留一個(gè)。這樣內(nèi)存四區(qū)如下

*3. 堆區(qū)
char *getMem(){

    char *p1 = NULL;
    p1 = (char *)malloc(sizeof(char)* 10);  //申請(qǐng)內(nèi)存空間
    return p1;
}

void main(){
    
    char *tmp = NULL;
    tmp = getMem();
    strcpy(tmp, "aaabbb"); //向tmp做指向的內(nèi)存空間中copy數(shù)據(jù)
    printf("tmp:%s.\n", tmp);
    getchar();

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 這幾天有朋友反映給小編說讓多發(fā)點(diǎn)關(guān)于面試的文章,小編深知從事IT行業(yè)的難處,跳槽多,加班多,薪資不樂觀,大多數(shù)朋友...
    諸葛青云999閱讀 10,271評(píng)論 0 6
  • 最全的iOS面試題及答案 iOS面試小貼士 ———————————————回答好下面的足夠了-----------...
    zweic閱讀 2,804評(píng)論 0 73
  • __block和__weak修飾符的區(qū)別其實(shí)是挺明顯的:1.__block不管是ARC還是MRC模式下都可以使用,...
    LZM輪回閱讀 3,609評(píng)論 0 6
  • 1.寫一個(gè)NSString類的實(shí)現(xiàn) +(id)initWithCString:(c*****t char *)nu...
    韓七夏閱讀 3,878評(píng)論 2 37
  • 學(xué)習(xí)跳古典舞第三天,《知否、知否》,雖然很美,但是好難跳的一個(gè)舞蹈,老師說我們從最開始的在地上連滾帶爬的,到現(xiàn)在可...
    花飛雪兒閱讀 191評(píng)論 0 0

友情鏈接更多精彩內(nèi)容