gpt4 book ai didi

c# - 现代 .Net 中未对齐的指针有多安全?

转载 作者:行者123 更新时间:2023-12-05 05:38:23 27 4
gpt4 key购买 nike

我需要从 native 内存读取/写入一堆结构。我想弄清楚我是否应该为结构对齐而烦恼。这是我编写的用于测试的简单代码。它将压缩结构写入未对齐的指针,然后读回该结构:

public static unsafe class Program
{
public static void Main()
{
Console.WriteLine(sizeof(MyStructPacked)); //returns 6, as expected (no padding)

var nativeMemory = Marshal.AllocHGlobal(33);

var ptr = (byte*)nativeMemory.ToPointer();
Console.WriteLine((int)ptr % 8 == 0); //true, pointer is aligned to 8 bytes
Console.WriteLine((int)ptr % 16 == 0); //true, pointer is also aligned to 16 bytes

Unsafe.InitBlock(ptr, 0, 33);
//!!! aligned write to unaligned pointer
Unsafe.Write(ptr + 3, new MyStructPacked{Short = ushort.MaxValue / 2, Int = UInt32.MaxValue});
for (int i = 0; i < 10; i++)
{
byte b = *(ptr + i);
//returns 0 0 0 255 127 255 255 255 255 0 (which is correct)
Console.WriteLine(b);
}

//!!! aligned read from unaligned pointer
var read1 = Unsafe.Read<MyStructPacked>(ptr + 3);
//unaligned read from unaligned pointer
var read2 = Unsafe.ReadUnaligned<MyStructPacked>(ptr + 3);
//!!! dereferencing unaligned pointer
var read3 = *(MyStructPacked*)(ptr + 3);

//all produce the same (correct) result.
Console.WriteLine(read1.Int + " " + read1.Short);
Console.WriteLine(read2.Int + " " + read2.Short);
Console.WriteLine(read3.Int + " " + read3.Short);

//!!! aligned read from unaligned pointer
var readInt1 = Unsafe.Read<uint>(ptr + 5);
//unaligned read from unaligned pointer
var readInt2 = Unsafe.ReadUnaligned<uint>(ptr + 5);
//!!! dereferencing unaligned pointer
var readInt3 = *(uint*)(ptr + 5);

//all return uint.MaxValue (also correct)
Console.WriteLine(readInt1);
Console.WriteLine(readInt2);
Console.WriteLine(readInt3);

Marshal.FreeHGlobal(nativeMemory);
}
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct MyStructPacked
{
public ushort Short;
public uint Int;
}

我在手头的几个系统(使用 .Net 6.0)上测试了它,它在它们上运行没有问题。规范说值类型必须以某种方式对齐,但我找不到任何关于如果指针未按照规范对齐的方式实际发生什么的信息。我能找到的最好的是它被认为是“未定义的行为”(提到 here ),这不是很有帮助。

所以我的问题是,上面的代码有多安全?我可以期望它在其他 .Net 支持的系统和平台上运行吗?或者它的工作纯粹是偶然的?如果它在某些系统上不起作用,那么最坏的情况是什么?这段代码会崩溃吗?有什么我可以做的来重现潜在的问题(也许在特定系统上运行它?)?欢迎在这里提出任何建议,谢谢。

附言我知道未对齐访问对性能的影响,但这些都是次要问题。目前主要关注的是执行安全。

最佳答案

我在 armv7 处理器上遇到了问题,这些问题在低端领域相对常见。如果您尝试取消引用未对齐的指针(使用安全的 ref 运算符或不安全的 *),它们实际上会抛出实际的异常。该问题很容易重现,并且异常消息非常明确。

所以最后我不得不手动对齐所有必须通过引用访问的非托管内存。这很乏味,但很好......易于管理。如果您不需要通过引用访问内存,Unsafe.ReadUnalignedUnsafe.WriteUnaligned 方法也可以防止异常(显然以访问速度为代价)。

关于c# - 现代 .Net 中未对齐的指针有多安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72923219/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com