.net - .net 中的固定 block

标签 .net pointers garbage-collection fixed unsafe

我对何时需要固定 block 有点困惑。我有一个例子,它给了我一个矛盾的场景,如下:

enum RoomType { Economy, Buisness, Executive, Deluxe };

struct HotelRoom
{
    public int Number;
    public bool Taken;
    public RoomType Category;

    public void Print()
    {
        String status = Taken ? "Occupied" : "available";
        Console.WriteLine("Room {0} is of {1} class and is currently {2}", Number, Category, status);
    }
}

我创建了一个函数,它将接受一个指向HotelRoom的指针

private unsafe static void Reserve(HotelRoom* room)
{
    if (room->Taken)
        Console.WriteLine("Cannot reserve room {0}", room->Number);
    else
        room->Taken = true;
}

在主要方法中我有以下内容:

unsafe static void Main(string[] args)
{
    HotelRoom[] myfloor = new HotelRoom[4];
    for (int i = 0; i < myfloor.Length; i++)
    {
        myfloor[i].Number = 501 + i;
        myfloor[i].Taken = false;
        myfloor[i].Category = (RoomType)i;
    }
    HotelRoom Room =  myfloor[1];
    Reserve(&Room);   //I am able to do this without fixed block.
    //Reserve(&myfloor[1]);  //Not able to do this so have to use fixed block below. 

    fixed (HotelRoom* pRoom = &myfloor[1])
    {
        Reserve(pRoom);
    }

    myfloor[1].Print();
    Room.Print();
}

我的困惑是我可以Reserve(&Room),但不能Reserve(&myfloor[1])。我认为他们正在做同样的事情 - 将 HotelRoom 结构的内存地址传递给 Reserve 函数。为什么我需要fixed来执行此操作?

最佳答案

Room 是存储在堆栈中的局部变量,而 myfloor 存储在堆中。垃圾收集器可以移动堆中的对象以压缩它(地址会改变),因此您需要“固定”它们。这就是为什么您需要 fixed 语句。

更新:

此外,还有一种方法可以在堆栈而不是堆上分配内存:

HotelRoom* fib = stackalloc HotelRoom[4];

在这种情况下,您不需要 fixed 语句。

小免责声明:能够做到这一点并不意味着您当然应该这样做。正如其他人已经提到的,这是一种非常非 .NET 的代码编写方式,所以我认为这个问题是理论上的。

关于.net - .net 中的固定 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10227577/

相关文章:

c - c 中奇怪的输出问题

.net - RegAsm VS RegSvc32 VS GAC

c# - 无法使 ONNX 模型的输入列名称起作用

ruby - 这两个方法参数定义有什么区别?

java - 在 Java 中什么时候选择 SerialGC、ParallelGC 而不是 CMS、G1?

garbage-collection - 为什么 Lua 使用垃圾收集器而不是引用计数?

c - 如何解决奇怪的变化值?

.net - 使用 .NET 实现全文搜索的理想功能语言

c# - 从 ASP.NET CORE 中的字节加载程序集

c - 当我用数组初始化指针时会发生什么?