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



我正在努力理解将结构作为结构的成员如何存储在内存中。据我所知,如果我们在内存中有一个简单的结构,例如

struct Simple {
int x;
bool y;
}

那么,如果我们在内存中初始化Simple s = new Simple(),我们会看到类似的连续内容

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

因此,如果我们调用s.x,那么我们将需要将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(),那么在内存中我们会有

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

无论CCD_ 5存储在存储器中的哪个位置,都需要单独提取。这是因为otherArray内的实际值不是与x连续存储的,而是对数据的引用在x之后连续。如果otherArray被初始化为Simple s = new Simple(1, new Simple[1]),那么otherArray数据是在x之后连续存储,还是otherArray总是一个引用类型(无论它是否在结构构造函数中初始化(?

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

struct Simple {
int x;
Other other;
}

这是我不清楚的地方。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)

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

我也很感激对我的逻辑进行任何更正,或者进一步了解不同类型如何在结构中存储在内存中,因为我正在努力理解C#如何在内存中存储数据,谢谢

otherArray数据是在x之后连续存储,还是otherArray始终是的参考类型

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

一个结构是作为与该结构相邻存储的结构的成员,还是只是作为另一个结构的实际数据的某种地址存储?

结构是值类型,因此不存在"到另一个结构的实际数据的某种地址";。这就是引用类型的作用。它不一定是连续的(但在OtherSimple的情况下是连续的(-如果不指定显式的PackLayoutKind,它将遵循默认的对齐规则。请参阅此处了解更多信息。

让我们考虑一下:

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字段实际上是一个地址,而不是您设置的值。

最新更新