sizeof()計算嵌套結構體

學習此資料指南

  • 不用看各種頭文件
  • 先從test::run2()極其前後註釋看起
  • 然後如果想要深入學習,可以看test::run()中的Variadic_template實現遞歸複合的sizeof()求解,太細的東西暫時看不懂沒關係,其實只用看數據,他就相當於run2()中的struct嵌套struct

關鍵

對於嵌套的結構體,需要將其展開。對結構體求sizeof時,上述兩種原則變爲:

  • 展開後的結構體的第一個成員的偏移量應當是被展開的結構體中最大的成員的整數倍。

  • 結構體大小必須是所有成員大小的整數倍,這裏所有成員計算的是展開後的成員,而不是將嵌套的結構體當做一個整體。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for(int i = int(a); i <= int(b); ++i)
#define per(i, b, a) for(int i = int(b); i >= int(a); --i)
#define mem(x, y) memset(x, y, sizeof(x))
#define SZ(x) x.size()
#define mk make_pair
#define pb push_back
#define fi first
#define se second
const ll mod=1000000007;
const int inf = 0x3f3f3f3f;
inline int rd(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;}
inline ll qpow(ll a,ll b){ll ans=1%mod;for(;b;b>>=1){if(b&1)ans=ans*a%mod;a=a*a%mod;}return ans;}

namespace test{
    template<typename... Values> class tuple;
    template<> class tuple<> { };

    template<typename Head,typename... Tail>
    class tuple<Head,Tail...>
    {
        typedef tuple<Tail...> composited;
    protected:
        composited m_tail;
        Head m_head;
    public:
        tuple() { }
        tuple(Head v,Tail... vtail)
         : m_tail(vtail...),m_head(v){ }

        Head head() { return m_head; }
        composited& tail() { return m_tail; }
    };

    void run(){
        tuple<int,float,string> t(41,6.3,"linmin");
        cout<< sizeof(t) <<endl;
        cout<< sizeof(int) <<endl;
        cout<< sizeof(float) <<endl;
        cout<< sizeof(string("linmin")) <<endl;

        cout<< t.head() << endl;
        cout<< t.tail().head() << endl;
        cout<< t.tail().tail().head() << endl;

        tuple<string,complex<int>,bitset<16>,double>
            it2("Ace",complex<int>(3,8),bitset<16>(377),3.141592453);
        cout<< sizeof(it2) <<endl;
        cout<< sizeof(string("Ace")) <<endl;
        cout<< sizeof(complex<int>(3,8)) <<endl;
        cout<< sizeof(bitset<16>(377)) <<endl;
        cout<< sizeof(double) <<endl;
        cout<< it2.head() <<endl;
        cout<< it2.tail().head() << endl;
        cout<< it2.tail().tail().head() << endl;
        cout<< it2.tail().tail().tail().head() << endl;
    }
    /*
這個size我無法理解,老師的輸出第一個竟然是16,第二個也是40

卡了一個多小時...2020年4月10日17:34:09 去查資料
2020年4月10日18:02:03 按照run2的分析之後就能懂得了爲什麼
這裏是32,首先是這裏一開始填4bytes,但是根據後面展開的結構體最寬的對齊
所以填完第一個的偏移量是8,之後填入4又同樣的原因第二個後偏移到16
之後8和最後展開的一個空的一起都各自爲8,所以是32

之後的40同理解釋
32
4
4
8
41
6.3
linmin
40
8
8
4
8
Ace
(3,8)
0000000101111001
3.14159
    */

/*
對於嵌套的結構體,需要將其展開。對結構體求sizeof時,上述兩種原則變爲:
       (1)展開後的結構體的第一個成員的偏移量應當是被展開的結構體中最大的成員的整數倍。

       (2)結構體大小必須是所有成員大小的整數倍,這裏所有成員計算的是展開後的成員,而不是將嵌套的結構體當做一個整體。

例子1:

struct stru5  
{  
      short i;  
      struct   
      {  
           char c;  
           int j;  
      } tt;   
      int k;  
};

結構體stru5的成員tt.c的偏移量應該是4,而不是2。整個結構體大小應該是16。
————————————————
版權聲明:本文爲CSDN博主「海月汐辰」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_37858386/article/details/75909852

*/

    void run2(){
        struct stru1
        {
            short i;
            struct
            {
                char c;
                int j;
            } tt;
            int kl;
        };
        struct stru2
        {
            short i;
            struct
            {
                char c;
                int j;
                struct{
                    // 估計多加4,事實確實
                } tt2;
            } tt;
            int kl;
        };
        struct stru3
        {
            string a;
            struct
            {
                // 估計加8
            } sT;
        };
        cout<< sizeof(stru1) <<endl;
        cout<< sizeof(stru2) <<endl;
        cout<< sizeof(stru3) <<endl;
        // 16
        // 20
        // 16
    }
}


int main(){
    test::run();
    test::run2();

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