5

在子主题Storage Overhead (on Chapter) - C# 5.0 in a Nutshell book -有这个一般说明说:

在此处输入图像描述

现在,我想知道为什么 struct A中的字段会浪费空间?或者,作者对整个笔记的观点是什么?

4

4 回答 4

8

每个byte字段占用 1 个字节,而每个long字段占用 8 个字节。这意味着,虽然b可以放置在内存中的任何位置,但l需要放置在 8 的倍数的地址。它不能放置在地址0,因为它已经被b;占用。因此,它必须放在下一个可用的 8 倍数处,即8,导致 7 个字节的中间空间被浪费。

---------------------------------------------------------------------------------
|  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |  8 |  9 | 10 | 11 | 12 | 13 | 14 | 15 |
---------------------------------------------------------------------------------
<--b->                                  <------------------l-------------------->
      <--------------waste------------->
于 2013-07-06T15:53:26.350 回答
5

只看对齐。Long 必须在位置 0, 8, 16,...

但是如果我们首先有字节,它看起来像这样:

b-------llllllll

用 b 蜂鸣字节 b 和 l 蜂鸣长 l。- 是“浪费的空间”所以你可以看到结构使用了整个 16 个字节,但只使用了 9 个字节,因此浪费了 7 个字节

于 2013-07-06T15:51:42.917 回答
3

结构的这种默认设置有两个原因:

1)性能,正如其他人已经解释的那样。将字段成员放置为其大小的倍数允许更快的传输。

2) 与大多数 C/C++ 编译器的默认值相同。这使得与 C/C++(包括所有 Windows API)的互操作更容易一些。

请注意,如果您不需要编组结构,您可以使用[StructLayout(LayoutKind.Auto)]

[StructLayout(LayoutKind.Auto)]
struct A
{
    byte b;
    long l;
}

有了它,下面的代码

unsafe
{
    Console.WriteLine(sizeof(A));
}

prints 12,这表明更好的包装。

如果您使用[StructLayout(LayoutKind.Sequential, Pack = 1)],您可以将尺寸缩小到9.

于 2013-07-06T17:01:45.720 回答
2

它们通常在处理器字边界处对齐,因此检索它们是一个简单的单周期操作。否则,CLR 将不得不获取整个地址,并对结构字段进行异或/移位以引用它。

于 2013-07-06T15:53:00.603 回答