幾種類型的內存模型

      今天和同學同事討論了一下static const等等類型在內存中的存儲,查了若干資料,總結如下:

 

1:一個由c/c++編譯的程序的內存分爲以下幾個部分


     1:BBS         存放全局數據和靜態數據

     2:DATA       存放常量字符串

     3:CODE      代碼

 

     4:Heap      

     5:  Stack

 

    這其中比較容易混淆的就是BBS與DATA區,很多人容易認爲二者是一個區,實際不是的。

 

2: 看幾個例子:

 

 

  上邊比較讓人難理解的是最後兩個,a5指向的"abc"是存儲在DATA上的,此時認爲這個“abc”是一個常量! 而a4是一個在棧上分配的數組空間,而後邊的“abc”僅僅是給其賦值用而已。

 

    而凡是static修飾的肯定是在BBS區。

 

3:上邊討論了幾個比較容易理解的,還有一個不容易理解的就是const! 對於const,和朋友剛開始討論的一個問題是:

      const  int a = 10;

      此時a是一個常量呢 還是一個大小不變的變量?  畢竟:如果是變量,則肯定不會存儲在DATA中。

 

      其實平時用的const,我們依舊可以對其進行修改!只要做個不同的指針來對其進行指向,而後用這個指針來進行內容修改即可!

但是這只是一種很片面的情況,說白了吧:只要我們能拿到一塊內存的地址,那我們完全可以在寫代碼時用這個指針來對內存進行操作,這樣:編譯時沒有任何問題!畢竟完全復合邏輯!

 

      對於const修飾的變量,其也有全局 和 局部 之分!

      ①:當其爲局部變量時:我們完全可以向平時那樣用指針對其進行修改!c和c++的處理方式是一樣的!亦即:此時變量是存放在棧上的!我們可以拿到地址!

      ②:當其爲全局變量時:c和c++的處理方式是不一樣的!c++在編譯時:編譯器會把這個它放到自己的符號表中!作爲編譯器常量!所以它是沒有地址的! 而c編譯時是認爲其有地址的!  這是兩種截然不同的處理方式,前者叫:內鏈接 後者叫:外連接!

         

       如上兩句,如果a是一個const全局變量, 那麼在c下這樣寫肯定是錯誤的!畢竟此時a爲一個地址。 但是在c++下沒有問題,因爲編譯器早把a存在符號表中作爲一個常量來使用!

 

       那麼對於c,既然可以取到const全局變量的地址,在後邊我們依舊可以用這個地址來對其進行修改操作! 顯然:這在編譯的時候不會報任何錯誤!連warnning都沒有,畢竟:完全復合邏輯! 但是運行時就會報錯說:segmentation fault。這是因爲:const全局變量是存放在 DATA區中的!此區受到寫保護! 就算你有地址指過來也無法修改!

       而對於c++而言:顯然其沒有地址指向這塊區域,那就談不上後邊的修改操作了,那麼寫肯定連編譯都通過不了。

 

總結一下const:

   1:對於const局部變量,其是存放在棧上的! 可以進行修改。

   2:對於const全局變量,其是存放在DATA區的!

 

    對於c語言:編譯時會採用外連接,有地址;

    對於c++預言:編譯時採用內鏈接,沒有地址,存放到符號表中作爲一個常量。

   --->那麼:在c中,後邊如果對其進行修改,編譯是沒有問題的,畢竟有地址指向。但是運行出錯!畢竟指向的區域不可修改!    

 

 

 

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