为什么允许从函数内返回不安全的指针?


2

我最近看到了几个实际做到这一点的开源项目;从函数返回一个不安全的指针,例如:“int * input = this.someIterator.GetUnsafePtr()”。

从我的理解,这必须是完全错误的。不安全的指针只能通过'固定'语句获得,当然从函数内部返回的指针不会再被固定(它们将'丢失'它们的声明范围),最终导致它们被垃圾收集。

但是后来我不记得编译器给出了有关这个的任何警告,那么为什么要使用一个固定的语句,如果你实际上可以有'unpinned'的指针遍布整个?

2

我从来没有在开源项目中看到这样的构造。如果你在你的问题中提供一些这样的用法的样本会更好。它的含义可能取决于行为。
但我同意,不安全的指针是邪恶的,只有当你与一些本地库或代码交互时才应该使用。
据我记得,只有在不安全的区块才能使用这种结构。所以我认为编译器在这里不会给出任何警告。 IMO最好使用IntPtr(不安全块只能在完全信任下执行)。
编辑:
@Stephen是正确的,IntPtr不会保留对GC收集对象的引用。

  0

IntPtr不是跟踪指针。如果一个IntPtr引用一个托管对象,并且该对象被移动,则该指针不会被更新。 IntPtr和不安全的指针之间没有真正的区别,除了IntPtr符合CLS并且不是'不安全'。 22 2月. 092009-02-22 13:16:28

  0

你是对的,谢谢。我认为我需要再次阅读有关CLR的内容。 22 2月. 092009-02-22 13:49:24


3

怎么样,Marshal.AllocHGlobalMarshal.AllocCoTaskMem,都返回IntPtr,它可以使用.ToPointer()函数自由投射到void *

或者指针可能来自非托管代码。你需要fix/pin内存,因为内存是托管的,因此只要它不是fixed/pinned垃圾收集器可以自由移动它,使指针无效。