C/C++的記憶體模型

來源:互聯網
上載者:User

 一、 記憶體模型的概念

        記憶體模型是C/C++資料抽象的基礎,是C/C++最底層的語言設施。不過,C與C++關於記憶體模型的表述方式是不同的。C++明確提出了記憶體模型的概念,但C沒有這樣做,而是對記憶體模型的構件例如bit和byte單獨定義。儘管形式不同,但兩者關於記憶體模型的語義是基本相同的,都由bit構成byte,bit是構成對象的最小單位,而可定址的最小資料存放區單位是byte,這意味著位域(bit-field)可以構成最小的對象,但不能使用取址運算子,例如下面代碼:

struct  x{    unsigned int  a  :  1;} ;struct  x  y;int *p = &y.a;   //非法,但y中的成員a是一個對象

 

byte內的bit是連續排列的,byte內的空間不存在類似位元組對齊那樣的填充物,即使一些在邏輯上將某些位視作填充物的場合,在byte看來仍然是正常的bit。例如:

struct  x{    int  a  :  2;    int     : x;   //x為某一數字     int  b  : 4;} ;

位域a和b之間有一個匿名位域,通常用於使下一個位域按某種方式對齊,以利於提高執行效率,在邏輯上這個匿名位域就是一個填充物,但從記憶體模型的角度看它依然是一個正常的位域對象。

二、位元組的長度

        一個byte應該有多少bit?很多人會衝口而出:8bit。當然,多數人所熟悉的環境的byte的確是8bit的,但是,如果據此以為C/C++所支援的所有系統的byte都是8位的,就大錯特錯了!事實上,C/C++標準支援某些一個byte超過8位的系統,C標準在其rational中解釋了這個問題:

3. Terms and definitions

• All objects in C must be representable as a contiguous sequence of bytes, each of which is at least 8 bits wide.

• A charwhether signed or unsigned, occupies exactly one byte.

(Thus, for instance, on a machine with 36-bit
words, a byte can be defined to consist of 9, 12, 18, or 36 bits, these numbers being all the exact divisors of 36 which are not less than 8.) These strictures codify the widespread presumption that any object can be treated as an array of
characters, the size of which is given by the sizeof operator with that object’s type as its operand.

有些字長36位的執行環境每個byte的構成可能是9、12、18和36位,都是不小於8的36的因數。因此,C/C++規定一個byte的二進位寬度是實現相關(implementation defined)的,至少由8bit構成,而非必定8位。

        為什麼至少8位?C/C++規定,byte的二進位寬度必須能夠表示基本執行字元集的所有字元,而基本執行字元集共有100個字元,需要7位二進位寬度,再加上C/C++數值表示的二進位編碼方式所需要的1個符號位,因此至少需要8位。

        C在limits.h(C++則為climits)標頭檔中使用了一個宏CHAR_BIT,用於指示當前編譯環境的byte的二進位寬度。一段高移植性的代碼不應該基於一個byte為8bit的假設。例如下面一段在面試中經常遇到的代碼:

unsigned char A[ 255 ]; unsigned char i;for ( i = 0; i <= 255; ++i ){      A[ i ] = i;    printf( "%d/n", i );}

這段代碼會有什麼結果?死迴圈通常是自以為是的出題者所認為的正確答案,但這個答案只正確了一半。這段代碼存在兩類不良設計:一是基於8位byte的假設;二是使用了255這個魔數,沒有進行局部化。在byte超過8位的環境中,上述代碼就不一定是死迴圈了。保證在任何符合標準的環境中都是死迴圈的改進是如下這樣的:

#include <limits.h>………………unsigned char A[ UCHAR_MAX ]; unsigned char i;for ( i = 0; i <= UCHAR_MAX; ++i ){      A[ i ] = i;    printf( "%d/n", i );}


UCHAR_MAX是limits中用於表示當前編譯環境unsigned char最大值的宏,在上述代碼中使用它能保證出現所希望的結果,無論實際的CHAR_BIT是多少。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.