c# – 为什么sizeof的struct是不安全的

MSDN明确指出

For all other types,including structs,the sizeof operator can only
be used in unsafe code blocks.

C# Language Specification更精确:

>成员被打包成一个结构体的顺序是未指定的.
>为了对齐目的,开始时可能有未命名的填充
一个结构体,一个结构体内部和结构体的结尾.
>用作填充的位的内容是不确定的.
>当应用于具有struct类型的操作数时,结果是该类型的变量中的总字节数,包括任何填充.

然而,CLR如何处理以下结构:

[StructLayout(LayoutKind.Explicit,Size = 1,Pack = 1)]
public struct MyStruct
{
    [FieldOffset(0)] public byte aByte;
}

public struct MyEmptyStruct { }

在MyStruct中,我们强制执行布局,大小以及如何通过StructLayout属性打包它.这个结构应该在内存中有1个字节的大小.

另一方面,MyEmptyStruct是空的,我们可以假设内存中的大小将为0字节 – 即使这样的结构很可能不会被使用,仍然是一个有趣的情况.

当使用sizeof(MyStruct)和sizeof(MyEmptyStruct)来计算这些结构的大小时,编译器会抛出以下错误

*‘ does not have a predefined size,therefore sizeof can only
be used in an unsafe context

我想知道为什么在这种情况下使用sizeof被认为是不安全的.问题不是要求解决方法,也不是要求计算结构体的大小的正确方法,而是关注原因.

解决方法

I would like to know why using sizeof in this context is considered unsafe.

马修·沃森(Matthew Watson)的评论打了头钉.你在安全代码中要怎么处理这些信息?对于任何东西(*)都没有用.它不告诉你需要分配给元帅的是多少个非管理字节?那是Marshal.SizeOf.它只对指针算术有用,那么为什么它应该在安全子集?

(*)可以公平地说,有一些奇怪的角落用例可以使用包含托管类型的结构体的安全大小.假设例如,你有一个通用的集合类,它将分配一堆数组,并希望确保这些数组不被移动到大对象堆中;如果您可以使用包含托管对象的结构体的大小,那么可以非常容易地编写该代码,并且不需要任何指针运算.但事实上,sizeof是专门针对指针算术而设计的,而不是这样,您可以围绕数组的垃圾回收启发式进行终端运行.

相关文章

在项目中使用SharpZipLib压缩文件夹的时候,遇到如果目录较深,则压缩包中的文件夹同样比较深的问题。比...
项目需要,几十万张照片需要计算出每个照片的特征值(调用C++编写的DLL)。 业务流程:选择照片...
var array = new byte[4]; var i = Encoding.UTF8.GetBytes(100.ToString("x2"));//...
其实很简单,因为Combox的Item是一个K/V的object,那么就可以把它的items转换成IEnumerable<Dic...
把.net4.6安装包打包进安装程序。 关键脚本如下: 头部引用字符串对比库 !include "WordFunc....
项目需求(Winform)可以批量打印某个模板,经过百度和摸索,使用iTextSharp+ZXing.NetʿreeSp...