gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 08:20:16 27 4
gpt4 key购买 nike

在 C# 中,可以声明一个具有指针类型成员的结构(或类),如下所示:

unsafe struct Node
{
public Node* NextNode;
}

使用这种结构是否安全(错误.. 暂时忽略那个具有讽刺意味的小 unsafe 标志..)?我的意思是在堆上长期存储。据我了解,GC 可以自由移动事物,并且在更新对已移动事物的引用时,它是否也更新指针?我猜不会,这会使这种结构非常不安全,对吧?

我敢肯定有很多更好的选择可以替代此操作,但称之为病态的好奇心。

编辑:似乎有些困惑。我知道这不是一个很好的构造,我纯粹想知道这是否是一个安全的构造,即:指针是否保证始终指向您最初指向的任何位置? p>

原始的 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”语句固定一个变量。

  • 使用互操作服务为您希望在一个地方保持事件状态的结构创建一个 gc 句柄。

做这些事情中的任何一个都极有可能破坏垃圾收集器的性能。

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

  • 只获取局部变量、值参数或堆栈分配 block 的地址。当然,在这样做时,您需要确保指针的存活时间不超过相关堆栈帧,否则,您就是在引用垃圾。

  • 从非托管堆中分配一个 block ,然后在该 block 内使用指针。本质上,实现你自己的内存管理器。您需要正确实现新的自定义内存管理器。小心。

关于C#:使用指针类型作为字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1703827/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com