32位和64位结构的大小

the*_*oop 6 .net architecture struct

.NET结构设计指南中,它将结构的最大合理大小赋予16个字节.如何确定结构的大小,是否受运行程序的体系结构的影响?这个值仅为32位,还是两个拱门?

Jon*_*eet 7

这不是一个硬性和快速的价值 - 它只是一个指导方针,一个经验法则.根据确切的情况,24或甚至32个字节仍然可以完全合理 - 但是如果你的结构变得那么大,那么你应该首先问自己它是否适合作为结构.它可能是 - 在这种情况下,在执行赋值或将参数传递给方法(等)的任何时候复制那些32字节的命中可能是正确的做法; 在其他情况下,你应该真正使用一个类.

至于如何确定结构的大小 - 通常它是相当明显的,因为通常值类型只包含其他值类型.如果你的结构包含引用(或IntPtr/ UIntPtr),那就更多了 - 但这种情况非常罕见.(正如Mehrdad指出的那样,为了对齐,还存在填充问题.)

然后,我发现我想要编写自己的结构非常罕见.你的情况怎么样?


Ale*_*ack 3

是的,结构体的大小受架构的影响。32 位中的 C# 结构在 4 字节边界对齐,在 64 位中它们是 8 字节边界对齐。

例子:

struct Foo
{
   int bar;
}
Run Code Online (Sandbox Code Playgroud)

该结构体的实例在 32 位进程中将占用 4 个字节,在 64 位进程中将占用 8 个字节,尽管“int bar”在 32 位和 64 位进程中只占用 4 个字节。

更新:

我对此做了一些测试。我写了这段代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3
{
    struct Bar
    {
        int a;
    }

    struct Foo
    {
        Uri uri;
        int a;
    }

    class Program
    {
        static void Main(string[] args)
        {
            Foo[] foo;
            long fooBefore = System.GC.GetTotalMemory(true);
            foo = new Foo[10];
            long fooAfter = System.GC.GetTotalMemory(true);

            Bar[] bar;
            long barBefore = System.GC.GetTotalMemory(true);
            bar = new Bar[10];
            long barAfter = System.GC.GetTotalMemory(true);

            Foo aFoo = new Foo();
            Bar aBar = new Bar();

            System.Console.Out.WriteLine(String.Format("[Foo] Size of array of 10: {0}, Marshal size of one: {1}", fooAfter - fooBefore, System.Runtime.InteropServices.Marshal.SizeOf(aFoo)));
            System.Console.Out.WriteLine(String.Format("[Bar] Size of array of 10: {0}, Marshal size of one: {1}", barAfter - barBefore, System.Runtime.InteropServices.Marshal.SizeOf(aBar)));
            System.Console.ReadKey();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

作为 64 位进程,我得到以下输出:

[Foo] Size of array of 10: 208, Marshal size of one: 16
[Bar] Size of array of 10: 88, Marshal size of one: 4
Run Code Online (Sandbox Code Playgroud)

作为 32 位进程,我得到以下输出:

[Foo] Size of array of 10: 92, Marshal size of one: 8
[Bar] Size of array of 10: 64, Marshal size of one: 4
Run Code Online (Sandbox Code Playgroud)

观察结果:

  • 简单的结构体 Bar 在 32 位和 64 位进程上似乎都占用 4 个字节
  • 另一个结构体 Foo 在 32 位上似乎占用 8 个字节(4 个字节用于 int,4 个字节用于对 Uri 的引用),但在 64 位上需要 16 个字节(4 个字节用于 int,8 个字节用于对 Uri 的引用) Uri,我认为4个字节用于对齐)