繁体   English   中英

C# struct 或 struct[] 作为 memory 中连续结构的成员

[英]C# struct or struct[] as member of struct contiguous in memory

我试图了解如何将结构作为结构的成员存储在 memory 中。 据我了解,如果我们在 memory 中有一个简单的结构,例如

struct Simple {
  int x;
  bool y;
}

那么如果我们在 memory 中初始化Simple s = new Simple()我们会看到类似

s(0x01) --> 0x01(x - 32 bits data, y - 32 bits data) 

因此,如果我们调用sx ,那么我们需要将s提取到 cpu 中,然后可以访问 x 和 y 进行操作,因为它们是连续的。

现在,如果我们有一个结构数组作为成员

struct Simple {
  int x;
  Other[] otherArray;

  Simple(int input, Other[] otherInput)
  {
    x = input;
    otherArray = otherInput;
  }
}

struct Other {
  bool y;
}

如果我们做Simple s = new Simple()那么在 memory 我们会有

s(0x01) --> 0x01(x - 32 bits, otherArray - 64 bit reference type) 

s.otherArray[0]存储在 memory 中的任何位置都需要单独获取。 这是因为otherArray中的实际值不与x连续存储,但对数据的引用在x之后是连续的。 如果otherArray被初始化为Simple s = new Simple(1, new Simple[1])otherArray数据是否会在 x 之后连续存储,或者otherArray总是以任何方式作为引用类型(无论它是否在结构构造函数中初始化) )?

最后,如果我们有一个结构体作为结构体的成员

struct Simple {
  int x;
  Other other;
}

这是我不清楚的地方。 Is Simple s = new Simple()现在存储为

s(0x01) --> 0x01(x - 32 bits data, other - 32 bits data of y as bool)

或者是

s(0x01) --> 0x01(x - 32 bits, other - some reference to the data containing y as bool)

换句话说,一个结构是作为结构的成员与结构连续存储的,还是简单地存储为另一个结构的实际数据的某种地址?

我还希望对我的逻辑进行任何更正或进一步了解不同类型如何存储在结构中的 memory 中,因为我试图大致了解 C# 如何将数据存储在 memory 中,谢谢,

otherArray数据是否会在x之后连续存储,或者otherArray总是以任何方式作为引用类型

otherArray始终是对数组 object 的引用,即使它只有一个元素。 结构布局是结构类型的属性,而不是特定结构值的属性。

结构是作为结构成员的结构与结构连续存储还是简单地存储为其他结构的实际数据的某种地址?

结构是值类型,因此没有“其他结构的实际数据的某种地址”。 这就是引用类型的作用。 它不一定是连续的,(但在OtherSimple的情况下是连续的) - 如果您未指定显式PackLayoutKind ,它将遵循默认的 alignment 规则。 请参阅此处了解更多信息。

让我们考虑一下:

struct Simple
{
    public int x;
    public Other other;
}

struct Other
{
    public int y;
}

和价值:

var s = new Simple();
s.x = unchecked((int)0xabcdefab);
s.other.y = 0x12345678;

您希望s的大小为 8 个字节,其值将包含数字0xabcdefab0x12345678

// prints 8
Console.WriteLine(sizeof(Simple));
// in an unsafe block, prints 12345678ABCDEFAB
Console.WriteLine(Marshal.ReadInt64(new IntPtr(&s)).ToString("X"));

您可以尝试向Other添加更多字段,并看到sizeof(Simple)增加

将此与引用类型进行比较:

struct Simple
{
    public int x;
    public OtherRef other;
}

class OtherRef
{
    public int y;
}

您现在不能使用&来获取地址,所以这里有一个sharplab链接来显示other字段确实是一个地址,而不是您设置的值。

暂无
暂无

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

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