题
有人能解释我为什么下面的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向右走,所以它仍然是你的过程中使用有效的内存
当然,使用固定块的外部的指针,因为这是一个非常坏主意 - 不这样做
不隶属于 StackOverflow