有人能解释我为什么下面的C#代码不会崩溃?为什么Visual Studio中实际上允许编译它?我的理解是,我得到一个固定的指针,但它仅在“固定”声明固定。当指针从“富”函数返回,阵列“AR”可以被收集。然后我强迫GC真正做到这一点,但连续写入内存(现在释放)不会导致任何错误。

class Program
{
    static unsafe byte* Foo()
    {
        byte[] ar = new byte[100];
        fixed (byte* ptr = ar)
        {
            return ptr;
        }
    }

    static unsafe void Main(string[] args)
    {
        byte* ptr = Foo();
        GC.Collect();
        for (int t = 0;;++t) ptr[t%100] = 0;
    }
}
有帮助吗?

解决方案

埃里克是正确的,但你可能想听到的答案是,“有时它保留地址的固定语句的外面是非常有用的。”

也许从指针内存由另一个固定语句已经固定在其他地方,并且是有意义的回报呢?编译器是不是想揣摩你,给喧闹的警告。

不过,我倒是希望CodeAnalysis或其他先进的工具,会介入在这些地方编译器让你切断自己的脚。

其他提示

只是因为内存被释放,并不意味着写入它会造成什么样的错误。当垃圾回收器回收内存,它只是将它标记为空闲,在它的内部存储器映射 - 它不给它回到OS向右走,所以它仍然是你的过程中使用有效的内存

当然,使用固定块的外部的指针,因为这是一个非常坏主意 - 不这样做

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top