简体   繁体   English

Memory C# 结构数组的布局

[英]Memory layout of C# array of struct

In C, if I have the following struct Data :在 C 中,如果我有以下结构Data

struct __attribute__((__packed__)) Data
{
    double x;
    int y;
};

And then create an array named val of this struct:然后为这个结构创建一个名为val的数组:

Data val[3];

All values stored in val (ie val[0].x , val[0].y , val[1].x , val[1].y , val[2].x and val[2].y are contiguous in memory.所有存储在val中的值(即val[0].xval[0].yval[1].xval[1].yval[2].xval[2].y是连续的在 memory 中。

Now, when having the following struct in C#:现在,当在 C# 中具有以下结构时:

[StructLayout(LayoutKind.Sequential, Pack=0)]
struct Data
{
    public double x;
    public int y;
}

And then create an array named val of this struct:然后为这个结构创建一个名为val的数组:

Data val[3];

I would expect that all values stored in val are contiguous in memory, which they are not (based on the tests that I have conducted).我希望存储在val中的所有值在 memory 中都是连续的,但它们不是(基于我进行的测试)。 In details, val[0].x and val[0].y are both contiguous, but they are not contiguous with val[1] (which, in turn, is not contiguous with val[2] ).详细地说, val[0].xval[0].y都是连续的,但它们与val[1]不连续(而后者又与val[2]不连续)。

My question is: in C#, how can I create a variable (that is an array) of a certain struct that all its elements and members are contiguous in memory?我的问题是:在 C# 中,如何创建某个结构的变量(即数组),该结构的所有元素和成员在 memory 中都是连续的?

Just to try it, I made a very simple project: using Pack=1 seems to pack perfectly fine to the smallest byte.为了尝试,我做了一个非常简单的项目:使用Pack=1似乎可以完美地打包到最小的字节。

Reproducing code (on a console app):重现代码(在控制台应用程序上):

[StructLayout(LayoutKind.Sequential, Pack=1)]
struct Data
{
    public double x;
    public int y;
}

class Program {
    static void Main()
    {
        Data[] val = new Data[3] {
            new Data { x = 0, y = 0 },
            new Data { x = 1, y = 1 },
            new Data { x = 2, y = 2 },
        };

        for(var i = 0; i < 3; i++)
        {
            Console.WriteLine("data[" + i + "].x = " + BitConverter.ToString(BitConverter.GetBytes(val[i].x)));
            Console.WriteLine("data[" + i + "].y = " + BitConverter.ToString(BitConverter.GetBytes(val[i].y)));
        }       

        unsafe {
            fixed (Data *p = &val[0])
            {
                byte *c = (byte *)p;
                for(var j = 0; j < 3; j++)
                {
                    for(var i = 0; i < Marshal.SizeOf<double>(); i++, c++)
                    {
                        if(i!=0) Console.Write("-");
                        Console.Write("{0:X2}", *c);
                    }
                    Console.WriteLine();
                    for(var i = 0; i < Marshal.SizeOf<int>(); i++, c++)
                    {
                        if(i!=0) Console.Write("-");
                        Console.Write("{0:X2}", *c);
                    }
                    Console.WriteLine();
                }
            }

        }
    }
}

Output: Output:

data[0].x = 00-00-00-00-00-00-00-00
data[0].y = 00-00-00-00
data[1].x = 00-00-00-00-00-00-F0-3F
data[1].y = 01-00-00-00
data[2].x = 00-00-00-00-00-00-00-40
data[2].y = 02-00-00-00
00-00-00-00-00-00-00-00
00-00-00-00
00-00-00-00-00-00-F0-3F
01-00-00-00
00-00-00-00-00-00-00-40
02-00-00-00

Which looks perfectly continuous to me, unless I'm missing something这对我来说看起来完全连续,除非我错过了什么

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM