Jul*_*anR 12 c# pointers unsafe
在C#中,可以声明一个具有指针类型成员的结构(或类),如下所示:
unsafe struct Node
{
public Node* NextNode;
}
Run Code Online (Sandbox Code Playgroud)
它是否安全(错误......忽略了那个具有讽刺意味的unsafe小旗......)使用这种结构?我的意思是在堆上长期存储.根据我的理解,GC可以自由移动,当它更新对已被移动的内容的引用时,它是否也更新了指针?我猜不是,这会使这种结构非常不安全,对吧?
我确信这样做有更好的选择,但称之为病态的好奇心.
编辑:似乎有些混乱.我知道这不是一个伟大的结构,我纯粹想知道这是否是一个安全的结构,即:指针保证指向你最初指向它的东西?
原始C代码用于遍历树(深度优先)而不递归,其中树存储在数组中.然后通过递增指针遍历数组,除非满足某个条件,然后将指针设置为NextNode,其中遍历继续.当然,在C#中也可以通过以下方式实现:
struct Node
{
public int NextNode;
... // other fields
}
Run Code Online (Sandbox Code Playgroud)
其中int是下一个节点的数组中的索引.但出于性能原因,我最终会摆弄指针和fixed数组以避免边界检查,而原始的C代码似乎更自然.
Eri*_*ert 12
使用这种结构是否安全?我的意思是在堆上长期存储.
是.这样做通常是愚蠢,痛苦和不必要的,但这是可能的.
根据我的理解,GC可以自由移动,当它更新对已被移动的内容的引用时,它是否也更新了指针?
不,这就是为什么我们让你把它标记为不安全.
我猜不是,这会使这种结构非常不安全,对吧?
正确.
我确信这样做有更好的选择,但称之为病态的好奇心.
当然有.
是指针保证指向你最初指向它的东西?
除非你确保发生这种情况.有两种方法可以做到这一点.
方法一:告诉垃圾收集器不要移动内存.有两种方法可以做到这一点:
使用"fixed"语句修复变量.
使用互操作服务在一个地方为您希望保持活动的结构创建一个gc句柄.
执行这些操作之一很可能会破坏垃圾收集器的性能.
方式二:不要引用垃圾收集器可能移动的内存.有两种方法可以做到这一点:
仅获取局部变量,值参数或堆栈分配块的地址.当然,在这样做时,您需要确保指针不会比相关的堆栈帧存活更长时间,否则,您将引用垃圾.
从非托管堆中分配一个块,然后在该块内使用指针.在本质上,实现自己的内存管理器.您需要正确实现新的自定义内存管理器.小心.
| 归档时间: |
|
| 查看次数: |
2467 次 |
| 最近记录: |