【问题标题】:.NET deletes pinned allocated buffer.NET 删除固定分配的缓冲区
【发布时间】:2018-07-12 18:16:38
【问题描述】:
我有以下代码来分配缓冲区
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”吗?
谢谢。
【问题讨论】:
标签:
.net
memory
c++-cli
allocation
【解决方案1】:
垃圾收集器在进行垃圾收集时会移动托管堆上的所有对象。这是其正常操作的一部分。这就是为什么指向托管对象的“常规”指针无效的原因,因为垃圾收集器可以随时移动它。
pin 指针将托管堆上的对象标记为“不要移动我!”,因此只要 pin_ptr 对象存在,指针就会保持有效。然后,您可以将 pin 指针传递给需要常规原始指针的方法,并且它指向的对象在 pin_ptr 对象被销毁之前不会移动。
所有这些都与托管堆有关。假设您展示的代码片段是 C++/CLI 代码,您使用 new 在常规 unmanaged 堆上分配一个数组。不需要固定,它不会自行移动。
如果您已完成array<UInt16>^ buffer = gcnew array<UInt16>(m_rawBufferSize);,那么您将需要该别针。
...GC 不时修改 ptrAcqBuffer。
我不确定那里发生了什么。我不确定pin_ptr 在您尝试给它提供一开始不在托管堆上的东西时会做什么,因此可能会出现奇怪的行为。反正你不需要别针,我就不用担心了。