Des*_*ted 3 c# arrays types unsafe
我在下面有一段代码,只有一行注释掉了.该CreateArray方法中发生的情况与注释掉的行相同.我的问题是,当行b->ArrayItems = d被取消注释时它为什么会起作用,但在注释掉时会返回垃圾?我不认为我必须"修复"任何东西,因为所有的信息都是不受管理的.这个假设是不正确的?
class Program
{
unsafe static void Main(string[] args)
{
someInstance* b = stackalloc someInstance[1];
someInstance* d = stackalloc someInstance[8];
b->CreateArray();
// b->ArrayItems = d;
*(b->ArrayItems)++ = new someInstance() { IntConstant = 5 };
*(b->ArrayItems)++ = new someInstance() { IntConstant = 6 };
Console.WriteLine((b)->ArrayItems->IntConstant);
Console.WriteLine(((b)->ArrayItems - 1)->IntConstant);
Console.WriteLine(((b)->ArrayItems - 2)->IntConstant);
Console.Read();
}
}
public unsafe struct someInstance
{
public someInstance* ArrayItems;
public int IntConstant;
public void CreateArray()
{
someInstance* d = stackalloc someInstance[8];
ArrayItems = d;
}
}
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 13
我的问题是为什么当行被取消注释时它可以工作,但在注释掉时返回垃圾.
注释行是掩盖 CreateArray引起的错误的原因.评论它暴露了这个bug.但无论如何,这个bug都存在.
正如规范明确指出:
在该函数成员返回时,将自动丢弃在执行函数成员期间创建的所有堆栈分配的内存块.
CreateArray函数分配一个块,存储指向块的指针,块被丢弃,现在你有一个指向垃圾块的指针.您需要到永远的指针存储到stackalloc'd块,使得块失效后存储可以被访问.如果您需要存储对它的引用,Heap会分配块,并且在完成后记得取消分配它.
请记住,在不安全的代码中,您需要完全了解托管内存模型的所有内容. 一切.如果您不了解托管内存的所有内容,请不要编写不安全的代码.
那就是说,让我们解决一下你似乎更大的困惑,那就是"什么时候需要修复内存来获取指针?" 答案很简单.当且仅当它是可移动内存时,您必须修复内存. 修复将可移动存储器转换为不可移动的存储器; 这就是修复的目的.
你只能拿一些不可移动的东西; 如果你取一个可移动的东西的地址然后移动那么显然地址是错误的.您需要确保在获取其地址之前内存不会移动,并且您需要确保在再次移动后不再使用该地址.
| 归档时间: |
|
| 查看次数: |
1348 次 |
| 最近记录: |