我有以下代码来分配缓冲区
uns16 m_rawBuffer = new uns16[m_rawBufferSize];
pin_ptr<uns16> ptrAcqBuffer = m_rawBuffer;
尽管它不时是pin_ptr,GC还是会修改ptrAcqBuffer。
固定指针是防止对象移动的内部指针 从移动垃圾收集堆指向。那就是 公用语言不会更改固定指针的值 运行。通过托管类的地址时,这是必需的 到非托管功能,以便地址不会更改 在解析非托管函数调用期间出乎意料。
这对我没什么...有人可以解释一下吗? 另外,因为我用“ new”创建了m_rawBuffer,所以我需要“ pin_ptr”吗?
谢谢。
答案 0 :(得分:2)
垃圾收集器在执行垃圾收集时都会移动托管堆上的所有对象。这是其正常操作的一部分。这就是指向托管对象的“常规”指针无效的原因,因为垃圾回收器可以随时移动它。
pin指针将托管堆上的对象标记为“别动我!”,因此只要存在pin_ptr
对象,该指针就保持有效。然后,您可以将pin指针传递给需要常规原始指针的方法,并且指向的对象在pin_ptr
对象被销毁之前不会移动。
所有这些都与托管堆有关。假设您显示的代码片段是C ++ / CLI代码,则使用new
在常规 unmanaged 堆上分配一个数组。固定不是必需的,它不会自行移动。
如果您已完成array<UInt16>^ buffer = gcnew array<UInt16>(m_rawBufferSize);
,则需要使用图钉。
... GC有时会修改ptrAcqBuffer。
我不确定那里发生了什么。我不确定pin_ptr
的作用是什么,当您尝试首先提供它不在托管堆上的内容时,因此可能会出现奇怪的行为。由于无论如何您都不需要别针,所以我不用担心。