<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      happyhippy

      這個世界的問題在于聰明人充滿疑惑,而傻子們堅信不疑。--羅素

          在C/C++中,struct類型中的成員的一旦聲明,則實例中成員在內存中的布局(Layout)順序就定下來了,即與成員聲明的順序相同,并且在默認情況下總是按照結構中占用空間最大的成員進行對齊(Align);當然我們也可以通過設置或編碼來設置內存對齊的方式,有關C/C++中(設置)內存對齊的討論,可以參考我以前寫的一篇面試手記《總結面試時沒有回答上的設置內存對齊方式問題》

          然而在.net托管環境中,CLR提供了更自由的方式來控制struct中Layout:我們可以在定義struct時,在struct上運用StructLayoutAttribute特性來控制成員的內存布局。默認情況下,struct實例中的字段在棧上的布局(Layout)順序與聲明中的順序相同,即在struct上運用[StructLayoutAttribute(LayoutKind.Sequential)]特性,這樣做的原因是結構常用于和非托管代碼交互的情形。如果我們正在創建一個與非托管代碼沒有任何互操作的struct類型,我們很可能希望改變C#編譯器的這種默認規則,因此LayoutKind除了Sequential成員之外,還有兩個成員Auto和Explicit,給StructLayoutAttribute傳入LayoutKind.Auto可以讓CLR按照自己選擇的最優方式來排列實例中的字段;傳入LayoutKind.Explicit可以使字段按照我們的在字段上設定的FieldOffset來更靈活的設置字段排序方式,但這種方式也挺危險的,如果設置錯誤后果將會比較嚴重。下面就看幾個示例,算下四個struct各占多少Byte?

      1.[StructLayout(LayoutKind.Sequential)]

      struct StructDeft//C#編譯器會自動在上面運用[StructLayout(LayoutKind.Sequential)]
      {
          
      bool i;  //1Byte
          double c;//8byte
          bool b;  //1byte
      }
          

          sizeof(StructDeft)得到的結果是24byte!啊哈,本身只有10byte的數據卻占有了24byte的內存,這是因為默認(LayoutKind.Sequential)情況下,CLR對struct的Layout的處理方法與C/C++中默認的處理方式相同,即按照結構中占用空間最大的成員進行對齊(Align)。10byte的數據卻占有了24byte,嚴重地浪費了內存,所以如果我們正在創建一個與非托管代碼沒有任何互操作的struct類型,最好還是不要使用默認的StructLayoutAttribute(LayoutKind.Sequential)特性。

       


      2.[StructLayout(LayoutKind.Explicit)]

      [StructLayout(LayoutKind.Explicit)]
      struct BadStruct
      {
          [FieldOffset(
      0)]
          
      public bool i;  //1Byte
          [FieldOffset(0)]
          
      public double c;//8byte
          [FieldOffset(0)]
          
      public bool b;  //1byte
      }

          sizeof(BadStruct)得到的結果是9byte,顯然得出的基數9顯示CLR并沒對結構體進行任何內存對齊(Align);本身要占有10byte的數據卻只占了9byte,顯然有些數據被丟失了,這也正是我給struct取BadStruct作為名字的原因。如果在struct上運用了[StructLayout(LayoutKind.Explicit)],計算FieldOffset一定要小心,例如我們使用上面BadStruct來進行下面的測試:

      StructExpt e = new StructExpt();
      e.c 
      = 0;
      e.i 
      = true;
      Console.WriteLine(e.c);

          輸出的結果不再是0了,而是4.94065645841247E-324,這是因為e.c和e.i共享同一個byte,執行“e.i = true;時”也改變了e.c,CPU在按照浮點數的格式解析e.c時就得到了這個結果。(有關浮點數討論可以參考我以前寫的《精確判斷一個浮點數是否等于0》)。所以在運用LayoutKind.Explicit時千萬別吧FieldOffset算錯了:)

       

      3.[StructLayout(LayoutKind.Auto)]

          sizeof(StructAuto)得到的結果是12byte。下面來測試下這StructAuto的三個字段是如何擺放的:

      unsafe
      {
            StructAuto s 
      = new StructAuto();
            Console.WriteLine(
      string.Format("i:{0}", (int)&(s.i)));
            Console.WriteLine(
      string.Format("c:{0}", (int)&(s.c)));
            Console.WriteLine(
      string.Format("b:{0}", (int)&(s.b)));
      }

      // 測試結果:
      i:1242180
      c:
      1242172
      b:
      1242181

          即CLR會對結構體中的字段順序進行調整,將i調到c之后,使得StructAuto的實例s占有盡可能少的內存,并進行4byte的內存對齊(Align),字段順序調整結果如下圖所示:

       


      4.空struct實例的Size

      struct EmptyStruct{}

          無論運用上面LayoutKind的Explicit、Auto還是Sequential,得到的sizeof(EmptyStct)都是1byte。

       


      結論:

      默認(LayoutKind.Sequential)情況下,CLR對struct的Layout的處理方法與C/C++中默認的處理方式相同,即按照結構中占用空間最大的成員進行對齊(Align)

      使用LayoutKind.Explicit的情況下,CLR不對結構體進行任何內存對齊(Align),而且我們要小心就是FieldOffset;

      使用LayoutKind.Auto的情況下,CLR會對結構體中的字段順序進行調整,使實例占有盡可能少的內存,并進行4byte的內存對齊(Align)。 

      posted on 2007-04-12 16:58  Silent Void  閱讀(6055)  評論(9)    收藏  舉報

      主站蜘蛛池模板: 国产老女人免费观看黄A∨片| 亚洲综合伊人久久大杳蕉| 亚洲第一无码AV无码专区| A毛片毛片看免费| 福泉市| 国产熟妇另类久久久久久| 亚洲国产成人不卡高清麻豆| 99久久国产福利自产拍| 北川| 亚洲欧美成人综合久久久| 东京热一精品无码av| 亚洲一区二区三区播放| 人妻少妇精品无码专区二区| 国产精品久久国产丁香花| 五月丁香六月综合缴清无码| 四虎影视一区二区精品| 91人妻熟妇在线视频| 波多野无码中文字幕av专区| 亚洲av成人无码天堂| 自拍偷拍一区二区三区四| 国内精品久久久久影院网站| 久久这里只有精品首页| 亚洲精品无码你懂的| 国产精品亚洲А∨怡红院| 福利一区二区视频在线| 四虎国产精品永久在线看| 91福利国产成人精品导航 | 中国国产免费毛卡片| 熟妇人妻av中文字幕老熟妇| 国产精品自在自线免费观看| 夜夜偷天天爽夜夜爱| 亚洲精品国产suv一区88| 国产真人无遮挡免费视频| 国产精品国产高清国产专区| 国产农村激情免费专区| 午夜福利偷拍国语对白| 激情亚洲内射一区二区三区| 香蕉乱码成人久久天堂爱| 乱人伦人妻系列| 国产成人亚洲精品自产在线| 国产免费高清69式视频在线观看|