淺析C/C++變數在記憶體中的分布_C 語言

來源:互聯網
上載者:User

C/C++變數在記憶體中的分布在筆試時經常考到,雖然簡單,但也容易忘記,因此在這作個總結,以加深印象。

先寫一個測試程式:

複製代碼 代碼如下:

#include <stdio.h> 
#include <malloc.h> 
int g_i = 100; 
int g_j = 200; 
int g_k, g_h; 
int main() 

    const int MAXN = 100; 
    int *p = (int*)malloc(MAXN * sizeof(int)); 
    static int s_i = 5; 
    static int s_j = 10; 
    static int s_k; 
    static int s_h; 
    int i = 5; 
    int j = 10; 
    int k = 20; 
    int f, h; 
    char *pstr1 = "MoreWindows123456789"; 
    char *pstr2 = "MoreWindows123456789"; 
    char *pstr3 = "Hello"; 

     
    printf("堆中資料地址:0x%08x\n", p); 

    putchar('\n'); 
    printf("棧中資料地址(有初值):0x%08x = %d\n", &i, i); 
    printf("棧中資料地址(有初值):0x%08x = %d\n", &j, j); 
    printf("棧中資料地址(有初值):0x%08x = %d\n", &k, k); 
    printf("棧中資料地址(無初值):0x%08x = %d\n", &f, f); 
    printf("棧中資料地址(無初值):0x%08x = %d\n", &h, h); 

    putchar('\n'); 
    printf("待用資料地址(有初值):0x%08x = %d\n", &s_i, s_i); 
    printf("待用資料地址(有初值):0x%08x = %d\n", &s_j, s_j); 
    printf("待用資料地址(無初值):0x%08x = %d\n", &s_k, s_k); 
    printf("待用資料地址(無初值):0x%08x = %d\n", &s_h, s_h); 

    putchar('\n'); 
    printf("全域資料地址(有初值):0x%08x = %d\n", &g_i, g_i); 
    printf("全域資料地址(有初值):0x%08x = %d\n", &g_j, g_j); 
    printf("全域資料地址(無初值):0x%08x = %d\n", &g_k, g_k); 
    printf("全域資料地址(無初值):0x%08x = %d\n", &g_h, g_h); 

    putchar('\n'); 
    printf("字串常量資料地址:0x%08x 指向 0x%08x 內容為-%s\n", &pstr1, pstr1, pstr1); 
    printf("字串常量資料地址:0x%08x 指向 0x%08x 內容為-%s\n", &pstr2, pstr2, pstr2); 
    printf("字串常量資料地址:0x%08x 指向 0x%08x 內容為-%s\n", &pstr3, pstr3, pstr3); 
    free(p); 
    return 0; 


運行結果(Release版本,XP系統)如下:

可以看出:
1. 變數在記憶體位址的分布為:堆-棧-代碼區-全域靜態-常量資料
2. 同一地區的各變數按聲明的順序在記憶體的中依次由低到高分配空間(只有未賦值的全域變數是個例外)
3. 全域變數和靜態變數如果不賦值,預設為0。 棧中的變數如果不賦值,則是一個隨機的資料。
4. 編譯器會認為全域變數和靜態變數是等同的,已初始化的全域變數和靜態變數分配在一起,未初始化的全域變數和靜態變數分配在另一起。

上面程式全在一個主函數中,下面增加函數調用,看看函數的參數和函數中變數會分配在什麼地方。

程式如下:

複製代碼 代碼如下:

#include <stdio.h> 
void fun(int i) 

    int j = i; 
    static int s_i = 100; 
    static int s_j; 

    printf("子函數的參數:        0x%p = %d\n", &i, i); 
    printf("子函數 棧中資料地址: 0x%p = %d\n", &j, j); 
    printf("子函數 待用資料地址(有初值): 0x%p = %d\n", &s_i, s_i); 
    printf("子函數 待用資料地址(無初值): 0x%p = %d\n", &s_j, s_j); 

int main() 

    int i = 5; 
    static int s_i = 100; 
    static int s_j; 

    printf("主函數 棧中資料地址: 0x%p = %d\n", &i, i); 
    printf("主函數 待用資料地址(有初值): 0x%p = %d\n", &s_i, s_i); 
    printf("子函數 待用資料地址(無初值): 0x%p = %d\n", &s_j, s_j); 
    putchar('\n'); 

    fun(i); 
    return 0; 


運行結果如下:

可以看出,主函數中棧的地址都要高於子函數中參數及棧地址,證明了棧的伸展方向是由高地址向低地址擴充的。主函數和子函數中待用資料的地址也是相鄰的,說明程式會將已初始化的全域變數和靜態變數分配在一起,未初始化的全域變數和靜態變數分配在一起。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.