c語言字節對齊問題(一)

在這裏只總結結構體的字節對齊問題,看下面的結構體

       struct   s1                                       

      {

                  char  a;

                  int      b;

                  short  c;

        };

       struct   s2                          

      {

                  char  a;

                  short  c;

                  int      b;

        };

那麼sizeof(s1) = 12,  sizeof(s1) = 8;

 

我們可以假定結構體在內存中的地址是0x0000開始的,那麼我們說的字節對齊就是(起始內存地址%自身類型字節) =  0;

所以在這裏簡單分析下s1是怎麼對齊的

 a的內存地址是0x0000,自身字節1,它是自然對齊的,

 b的自身類型字節是4,如果要對齊,那麼起始地址只能是0x0004,範圍到0x0007.

 c的自身類型字節是2,故起始地址爲0x0008,範圍到0x0009故不用填充了直接跟在b變量後面,

 

爲什麼還要補全兩個字節呢,因爲假定這是一個結構體數組,那麼,下個元素的起始地址是不是也要對齊,所以不管後面有沒有變量,都要內存對齊,纔不會對後面的變量產生字節不對齊的影響,並且結構體最後補全的字節數取決於變量的最大類型的整數倍,即,在上面是int佔四字節,所以結構體的內存必然是4的倍數

 

當結構體中有char a[0]成員,這樣的成員時,這是不會增加結構體內存的,但是a的地址是上面那個成員的地址加一,也就是a後面的成員的地址


補充:對於改變指定字節的方法有幾種

一.

#pragma  pack  (n)   //n就是指定的字節

     struct  ss{

    .......

    };

#pragma pack ()   //取消指定字節

 

二.

struct ss

{

.....

}__attribute__ ((packed));   //指定最小字節對齊,一個字節

 

三.

struct stu{
   ....
}__attribute__ ((aligned (1)));  //數字爲指定一個字節

 

 

在這裏說一下,這是筆者自己的理解,對於不同平臺有不同的規定,像X86平臺,字節不對齊只是影響cpu讀取內存的速度,但是有些平臺必須嚴格對齊,不然會發送錯誤。這麼說那麼就是說cpu也不是按程序員想象那樣,int型的就一次去取int型所佔有的字節數,而是按照變量存儲在內存中什麼位置來決定取的次數,接着纔是取多少個字節,有不同看法的請指教

 

補充:如果能分析下面的結構體內存,你就真懂了字節對齊

struct aa
{
       char a;
       int b;
       double c;
};

struct bb
{
       char d; 
       struct
       {
              int e;
              double f;
       };
       int g;
};

 

結果是sizeof(aa) = 16; sizeof(bb) = 32

提示:其實結構體套結構體也是一樣的都是按最大字節對齊(按結構體中最大的類型對齊,不是類型的疊加),比如上面的struct bb;自己思考吧

 

 

下一篇是關於位域在struct中佔的內存

 

發佈了34 篇原創文章 · 獲贊 17 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章