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

前端之家收集整理的这篇文章主要介绍了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是专门针对指针算术而设计的,而不是这样,您可以围绕数组的垃圾回收启发式进行终端运行.

猜你在找的C#相关文章