C#:使用指针类型作为字段?

前端之家收集整理的这篇文章主要介绍了C#:使用指针类型作为字段?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在C#中,可以声明一个具有指针类型成员的结构体(或类),如下所示:
unsafe struct Node
{
  public Node* NextNode;
}

这是永远安全的(错误..忽略一点讽刺的小不安全的旗帜..)使用这个建设?我的意思是长期存储在堆上.根据我的理解,GC可以随意移动,当它更新对被移动的内容的引用时,它是否也更新指针?我猜不,这会使这个建筑非常不安全吗?

我相信有这样做的优点,但称之为病态好奇心.

编辑:似乎有一些混乱.我知道这不是一个伟大的建设,我纯粹想知道这是否是一个安全的建设,即:指针是否保持指向你最初指向的一切?

原始C代码用于遍历树(深度优先)而不进行递归,其中树存储在数组中.然后通过递增指针来遍历数组,除非满足某个条件,则指针将设置为NextNode,继续遍历.当然,C#可以通过以下方式实现:

struct Node
{
  public int NextNode;
  ... // other fields
}

其中int是下一个节点的数组中的索引.但是出于性能原因,我最终会使用指针和固定数组来避免边界检查,原来的C代码似乎更为自然.

解决方法

Is it ever safe to use this construction? I mean for long term storage on the heap.

是.这样做通常是愚蠢的,痛苦的和不必要的,但它是可能的.

From what I understand,the GC is free to move things around,and while it updates the references to something that’s been moved,does it update pointers too?

不,这就是为什么我们让你把它标记为不安全的原因.

I’m guessing no,which would make this construction very unsafe,right?

正确.

I’m sure there are way superior alternatives to doing this,but call it morbid curiosity.

当然有.

is the pointer guaranteed to keep pointing to whatever you originally pointed it to?

除非您确保发生这种情况.有两种方法可以做到这一点.

方式一:告诉垃圾回收器不要移动内存.有两种方法可以做到这一点:

>使用“fixed”语句修正一个变量.
>使用interop服务来创建一个gc句柄,以便您希望保持活动并在一个地方.

这些事情中的任何一个都很可能会破坏垃圾收集器的性能.

方法二:不要引用垃圾收集器可能移动的内存.有两种方法可以做到这一点:

>只接收局部变量,值参数或堆栈分配块的地址.当然,在这样做时,您需要确保指针不会比相关堆栈框架更长时间,否则您引用垃圾.>从非托管堆中分配一个块,然后使用该块内的指针.实质上,实现你自己的内存管理器.您需要正确实现新的自定义内存管理器.小心.

原文链接:https://www.f2er.com/csharp/97351.html

猜你在找的C#相关文章