获取指向字节数组的指针的不安全方法

ura*_*ray 4 c# pointers unsafe

这种行为在C#中是否有效

public class MyClass
{
    private byte[] data;
    public MyClass()
    {
        this.data = new byte[1024];
    }
    public unsafe byte* getData()
    {
        byte* result = null;
        fixed (byte* dataPtr = data)
        {
            result = dataPtr;
        }
        return result;
    }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 17

如果您要关闭安全系统,那么您有责任确保程序的内存安全.一旦你这样做,你需要安全地做所有事情,而安全系统不会帮助你.这就是"不安全"的含义.

正如C#规范明确指出:

只能使用固定语句获取可移动变量的地址,并且该地址仅在该固定语句的持续时间内有效.

您正在获取可移动变量的地址,然后在fixed语句的持续时间之后使用它,因此该地址不再有效.因此,您特别要求不做您正在做的事情.

在深入了解必须遵循的规则之前,不应编写任何不安全的代码.首先阅读规范第18章的全部内容.

  • @thefiloe:我知道这一点.那是怎么相关的,你认为我的哪句话是错的? (6认同)

Jar*_*Par 11

这段代码编译得很好但会导致运行时问题.代码基本上是走私指向堆中未固定对象的指针.移动MyClass类型的下一个GC 也将data使用它移动引用,之前返回的任何值getData现在将指向不正确的位置.

var obj = new MyClass();
unsafe byte* pValue = obj.getData();
// Assuming no GC has happened (bad assumption) then this works fine
*pValue = 42;

// Assume a GC has now happened and `obj` moved around in the heap.  The 
// following code is now over writing memory it simply doesn't own
*pValue = 42;
Run Code Online (Sandbox Code Playgroud)

最后一行是否导致应用程序崩溃,覆盖string另一种类型的值,或者只是将一个值戳到一个未初始化的数组中,然后搞砸了数学问题呢?你不知道.最好的结果是代码只是快速崩溃,但在所有可能的情况下,它会做一些更微妙和邪恶的事情.