【发布时间】:2021-06-30 10:49:06
【问题描述】:
我试图了解如何将结构作为结构的成员存储在内存中。据我了解,如果我们在内存中有一个简单的结构,例如
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)
s.otherArray[0] 需要单独获取,无论它存储在内存中的何处。这是因为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)
换句话说,一个结构体是作为结构体的成员与结构体连续存储,还是简单地存储为另一个结构体实际数据的某种地址?
我也希望能更正我的逻辑或进一步了解不同类型如何存储在 struct 中的内存中,因为我试图大致了解 C# 如何在内存中存储数据,谢谢
【问题讨论】:
-
Other 是指向其余数据所在位置的指针。在 c# 中,结构被包装,因为 c# 被管理以防止在找到空地址时出现异常。在直接的 c 语言中,没有包装器,所以 other 是一个指针,但可能是 other 后面的地址。 c# 中的包装器作为您看不到的其他内部字节。
-
@jdweng 真的吗?我通过使用
Marshal.ReadInt64阅读结构的内容发现了相反的结果。另一个观察结果是,当Other的大小增长时,Simple的大小也会增长。 -
SharpLab 的
Inspect.Stack将它们显示为一个连续的组合对象。并且Unsafe.SizeOf适当增加/减少。看到这个sharplab(并取消注释两行注释)sharplab.io/… -
@Sweeper :您是否验证了使用 sizeof() 观察到的内容?
-
@jdweng 是的,它表明
other不是指针。
标签: c# memory struct memory-management