.NET删除固定的分配缓冲区

时间:2018-07-12 18:16:39

标签: .net memory c++-cli allocation

我有以下代码来分配缓冲区

uns16 m_rawBuffer = new uns16[m_rawBufferSize];
pin_ptr<uns16> ptrAcqBuffer = m_rawBuffer;

尽管它不时是pin_ptr,GC还是会修改ptrAcqBuffer。

From the document我看到

  

固定指针是防止对象移动的内部指针   从移动垃圾收集堆指向。那就是   公用语言不会更改固定指针的值   运行。通过托管类的地址时,这是必需的   到非托管功能,以便地址不会更改   在解析非托管函数调用期间出乎意料。

这对我没什么...有人可以解释一下吗? 另外,因为我用“ new”创建了m_rawBuffer,所以我需要“ pin_ptr”吗?

谢谢。

1 个答案:

答案 0 :(得分:2)

垃圾收集器在执行垃圾收集时都会移动托管堆上的所有对象。这是其正常操作的一部分。这就是指向托管对象的“常规”指针无效的原因,因为垃圾回收器可以随时移动它。

pin指针将托管堆上的对象标记为“别动我!”,因此只要存在pin_ptr对象,该指针就保持有效。然后,您可以将pin指针传递给需要常规原始指针的方法,并且指向的对象在pin_ptr对象被销毁之前不会移动。

所有这些都与托管堆有关。假设您显示的代码片段是C ++ / CLI代码,则使用new在常规 unmanaged 堆上分配一个数组。固定不是必需的,它不会自行移动。

如果您已完成array<UInt16>^ buffer = gcnew array<UInt16>(m_rawBufferSize);,则需要使用图钉。

  

... GC有时会修改ptrAcqBuffer。

我不确定那里发生了什么。我不确定pin_ptr的作用是什么,当您尝试首先提供它不在托管堆上的内容时,因此可能会出现奇怪的行为。由于无论如何您都不需要别针,所以我不用担心。