[英]C# struct or struct[] as member of struct contiguous in memory
I am trying to understand how having a struct as a member of a struct would be stored in memory.我试图了解如何将结构作为结构的成员存储在 memory 中。 From what I understand, if we had a simple struct in memory, for example
据我了解,如果我们在 memory 中有一个简单的结构,例如
struct Simple {
int x;
bool y;
}
then in if we initialized Simple s = new Simple()
in memory we would see something contiguous like那么如果我们在 memory 中初始化
Simple s = new Simple()
我们会看到类似
s(0x01) --> 0x01(x - 32 bits data, y - 32 bits data)
so if we called sx
then we would need to fetch s
into the cpu and then have access to both x and y for operations since they are contiguous.因此,如果我们调用
sx
,那么我们需要将s
提取到 cpu 中,然后可以访问 x 和 y 进行操作,因为它们是连续的。
Now if we had an array of structs as a member现在,如果我们有一个结构数组作为成员
struct Simple {
int x;
Other[] otherArray;
Simple(int input, Other[] otherInput)
{
x = input;
otherArray = otherInput;
}
}
struct Other {
bool y;
}
if we did Simple s = new Simple()
then in memory we would have如果我们做
Simple s = new Simple()
那么在 memory 我们会有
s(0x01) --> 0x01(x - 32 bits, otherArray - 64 bit reference type)
s.otherArray[0]
would need to be fetched separately wherever it is stored in memory. s.otherArray[0]
存储在 memory 中的任何位置都需要单独获取。 This is because the actual values within otherArray
are not contiguously stored with x
but the reference to the data is contiguous after x
.这是因为
otherArray
中的实际值不与x
连续存储,但对数据的引用在x
之后是连续的。 If otherArray
is initialized as Simple s = new Simple(1, new Simple[1])
, would otherArray
data be stored contiguously after x or is otherArray
always going to be a reference type either way (whether it's initialized in the struct constructor or not)?如果
otherArray
被初始化为Simple s = new Simple(1, new Simple[1])
, otherArray
数据是否会在 x 之后连续存储,或者otherArray
总是以任何方式作为引用类型(无论它是否在结构构造函数中初始化) )?
Finally, if we have a struct as a member of a struct最后,如果我们有一个结构体作为结构体的成员
struct Simple {
int x;
Other other;
}
this is where it is unclear for me.这是我不清楚的地方。 Is
Simple s = new Simple()
now stored as Is
Simple s = new Simple()
现在存储为
s(0x01) --> 0x01(x - 32 bits data, other - 32 bits data of y as bool)
or is it或者是
s(0x01) --> 0x01(x - 32 bits, other - some reference to the data containing y as bool)
In other words, is a struct as a member of struct stored contiguously with the struct or is it simply stored as some sort of address to the actual data of the other struct?换句话说,一个结构是作为结构的成员与结构连续存储的,还是简单地存储为另一个结构的实际数据的某种地址?
I would also appreciate any correction to my logic or further knowledge on how different types are stored in memory within struct as I am trying to generally understand how C# stores data in memory, thank you我还希望对我的逻辑进行任何更正或进一步了解不同类型如何存储在结构中的 memory 中,因为我试图大致了解 C# 如何将数据存储在 memory 中,谢谢,
would
otherArray
data be stored contiguously afterx
or isotherArray
always going to be a reference type either wayotherArray
数据是否会在x
之后连续存储,或者otherArray
总是以任何方式作为引用类型
otherArray
is always going to be a reference to an array object, even if it only has one element. otherArray
始终是对数组 object 的引用,即使它只有一个元素。 The struct layout is a property of the struct type, not a property of particular struct values.结构布局是结构类型的属性,而不是特定结构值的属性。
is a struct as a member of struct stored contiguously with the struct or is it simply stored as some sort of address to the actual data of the other struct?
结构是作为结构成员的结构与结构连续存储还是简单地存储为其他结构的实际数据的某种地址?
Structs are value types, so there is no "some sort of address to the actual data of the other struct".结构是值类型,因此没有“其他结构的实际数据的某种地址”。 That's what reference types would do.
这就是引用类型的作用。 It's not contiguous necessarily, (but it is contiguous in the case of
Other
and Simple
) - it will follow the default alignment rules if you don't specify an explicit Pack
or LayoutKind
.它不一定是连续的,(但在
Other
和Simple
的情况下是连续的) - 如果您未指定显式Pack
或LayoutKind
,它将遵循默认的 alignment 规则。 See here for more info.请参阅此处了解更多信息。
Let's consider:让我们考虑一下:
struct Simple
{
public int x;
public Other other;
}
struct Other
{
public int y;
}
and the value:和价值:
var s = new Simple();
s.x = unchecked((int)0xabcdefab);
s.other.y = 0x12345678;
You'd expect the size of s
be 8 bytes, and its value will contain the numbers 0xabcdefab
and 0x12345678
:您希望
s
的大小为 8 个字节,其值将包含数字0xabcdefab
和0x12345678
:
// prints 8
Console.WriteLine(sizeof(Simple));
// in an unsafe block, prints 12345678ABCDEFAB
Console.WriteLine(Marshal.ReadInt64(new IntPtr(&s)).ToString("X"));
You can try adding more fields to Other
, and see that sizeof(Simple)
increases您可以尝试向
Other
添加更多字段,并看到sizeof(Simple)
增加
Compare this to a reference type:将此与引用类型进行比较:
struct Simple
{
public int x;
public OtherRef other;
}
class OtherRef
{
public int y;
}
You can't use &
to get the address now, so here's a sharplab link to show that the other
field is indeed an address, rather than the value you set it.您现在不能使用
&
来获取地址,所以这里有一个sharplab链接来显示other
字段确实是一个地址,而不是您设置的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.