C++進程空間堆棧的圖解與代碼註釋

C與C++的進程空間化成了好多的區間,這些區間存儲的內容並不同。下面利用代碼進行解析。
這裏寫圖片描述
上圖是進程空間的結構。
(注):很多書上講到堆是向上增,棧是向下降。這種說話很不明確,因爲不同的書上有不同的畫法。準確的說是堆向高地址增長,棧向低地址增長。
一段C或C++的代碼,具體的變量到底怎麼存儲如下:

#include<stdio.h>
#include<malloc.h>

int a = 1;//已初始化數據全局變量
int b;//未初始化數據
void main()
{
    int b; //局部變量,注意,只是局部變量,因爲在函數中定義。存在棧中。
    char[] = "abc"; //局部變量 存在棧中。
    char *p1; //局部指針變量,存在棧中。
    char *p2 = "12345"; //12345屬於常量,在常量區內存儲。其中常量屬於已初始化數據,在data去,因爲常量可以賦給任何變量。
    static int C = 0;//靜態變量,在已初始化區
    p1 = (char*)malloc(sizeof(char));
    p2 = (int*)malloc(sizeof(int));
    //上面變量p1與p2在棧中,利用malloc申請的區域在堆中
    free(p1);
    free(p2);
    //free函數會清除掉堆中的函數。
}

(一),入棧與出棧
棧的利用系統都會自動完成順序也很明確,當從main函數入口時。局部變量依次入棧,函數調用結束再依次出棧,因此順序很明確。
(二),堆空間的使用
(1),爲何要用堆的空間,先看下面的例子:讀入一個含n個整數的數組。代碼如下:

#include"csapp.h"
#define MAIX 100

int array[MAIX];// 此數組存在初始化區;
int main()
{
    int i n;
    scanf("%d",&n);
    if (n > MAIX)
    {
        app_error("too big");
    }
    for(i = 0;i < n;i++)
    {
        scanf("%d",&array[i]);
    }
    exit(0);
}

上面的代碼沒有任何的毛病,但問題在維護上。因爲只能接受100大小的數組,大的話會報錯,當然可以把數組設的很大,但是會造成內存的浪費和維護的麻煩。甚至來說,如果數組太大,會造成內存泄露。
(2),堆的好處
上面的代碼存在初始化數據區顯然不合適,這就引出堆的好處,要多少內存給多少,並且能夠及時回收。

#include"csapp.h"

int main()
{
    int i n *array;  //array這個指針在棧裏存着
    scanf("%d",&n);
    array = (int*)malloc(n*sizeof(int));//array指針指向堆區的一個地址,大小爲自己申請。
    for(i = 0;i < n;i++)
    {
        scanf("%d",&array[i]);
    }
    free(array);//不會造成內存浪費
    exit(0);
}

注:(1)向堆申請內存的方式在C++的實例化對象的部分會更爲顯著。
(2)堆棧的用法與細節比這要更爲的複雜,此文章只是簡要的概述大致過程。
(3)希望有理解錯的地方各位及時指正,謝謝。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章