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

2024-04-24

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

unsafe struct Node
{
  public Node* NextNode;
}

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

我确信有更好的选择来做到这一点,但称之为病态好奇心。

编辑:似乎有些混乱。我知道这不是一个伟大的建筑,我purely想知道这是否是一个安全的构造,即:指针是否保证继续指向您最初指向的内容?

原始的 C 代码用于在没有递归的情况下遍历树(深度优先),其中树存储在数组中。然后通过递增指针来遍历数组,除非满足特定条件,否则将指针设置为 NextNode,继续遍历。当然,在 C# 中也可以通过以下方式完成同样的任务:

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

哪里的int是数组中下一个节点的索引。但出于性能原因,我最终会摆弄指针和fixed无论如何,数组都可以避免边界检查,并且原始的 C 代码似乎更自然。


使用这种结构安全吗?我的意思是在堆上长期存储。

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

据我了解,GC 可以自由地移动事物,当它更新对已移动事物的引用时,它是否也会更新指针?

No. 这就是为什么我们让您将其标记为不安全。

我猜不会,这会让这个建筑非常不安全,对吗?

Correct.

我确信有更好的选择来做到这一点,但称之为病态好奇心。

当然有。

指针是否保证继续指向您最初指向的内容?

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

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

  • 使用“fixed”语句将变量固定到位。

  • 使用互操作服务为您希望在一个位置保持活动的结构创建一个 gc 句柄。

执行这些操作中的任何一个都很可能会破坏垃圾收集器的性能。

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#:使用指针类型作为字段? 的相关文章

随机推荐

  • HTTP 500 响应通过 RawXmlMessage.aspx 通过仪表板将 CCTray 连接到 CC.NET 服务器

    我正在使用 CC NET 1 6 服务器及其相应的 CCTray 通过远程处理轻松连接 但需要更改为通过 HTTP 使用仪表板连接 以便我可以开始将 URL 外包给开发人员 将我的仪表板 URL 放入 CCTray 中 http local
  • 有没有办法在 Shadow-DOM 中访问 CSS 中的 HTML 标签属性?

    我正在使用 StencilJS 创建一个自定义组件 当用户使用键盘或鼠标导航到该组件时 我必须对轮廓进行一些更改 我的组件正在使用 ShadowDOM 我想从 CSS 访问 HTML 标签属性 标签的属性是通过 What input 生成的
  • 从多个数据帧中提取公共行的子集

    我有多个数据框 如下所述 每行都有唯一的 id 我试图找到公共行并创建一个至少出现在两个数据框中的新数据框 示例 Id 2 的行出现在所有三个数据框中 类似地 df1 和 df3 中存在 Id 3 的行 我想创建一个循环 可以找到公共行并创
  • sqlite通过命令行导入csv时出错

    sqlite3 test sql SQLite version 3 6 12 Enter help for instructions Enter SQL statements terminated with a sqlite gt crea
  • 如何从后台服务更新 Android Activity 中的信息

    我正在尝试创建一个简单的Android应用程序 它有一个ActivityList信息 当应用程序启动时 我计划启动一个服务 它将不断计算数据 它会改变 并且我希望ActivityList与服务在应用程序生命周期内计算的数据 如何将我的活动设
  • 为什么 Groovy/Grape 不能解析来自 Maven Central 的工件?

    通过全新下载的 Groovy 2 1 9 我创建了 Test Groovy Grab commons io commons io 1 2 import org apache commons io CopyUtils println Reso
  • 与受保护的内部成员的可访问性不一致

    尝试在公共类中创建受保护内部类的受保护内部成员会导致以下问题 可访问性不一致 字段类型 what Class1 ProtectedInternalClass 比字段更难访问 what Class1 SomeDataProvider data
  • 安装 PyQt

    我正在尝试在我的 mac 上安装 PyQt 以便可以安装 python Ghost 我已经安装了Qt和SIP 我已经下载了 PyQt 但是当我运行时 python configure ng py 我收到以下错误 Error Use the
  • 我可以在 reStructuredText 中使用内联原始 LaTeX

    我正在尝试将 LaTeX 变量嵌入到一些 reStructuredText 中 我知道 raw 指令 但我希望将其嵌入到文本段落中 具体来说 我希望从模板考试文档中复制 numquestions 和 numpoints 变量 我尝试过使用
  • yaml.parser.ParserError:解析块映射时

    ERROR yaml parser ParserError while parsing a block mapping in tmp statelesscs compose yml line 1 column 1 expected
  • github 存储库的本地缓存?

    我们使用 github 来管理我们的大量软件环境 我敢打赌 像许多其他组织一样 该存储库的绝大多数流量来自我们的办公室 考虑到这一点 有没有一种方法可以构建给定 github 存储库的本地缓存 但仍然具有云版本的保护 我在缓存代理服务器的模
  • 设置 stats_flutter 时间序列图表中时间标签的格式以包含 hh:mm:ss

    是否可以格式化charts flutter时间序列图表的x轴上的标签以进行显示hh mm ss 这个答案 https stackoverflow com a 51138909 1954993解释了如何格式化代码以显示月份和日期 但我需要显示
  • 快速加速平均值和标准差

    我正在研究 Accelerate 以计算 Swift 中数组的平均值和标准差 我可以做到这一点 如何计算标准差 let rr Double 18 0 21 0 41 0 42 0 48 0 50 0 55 0 90 0 var mn Dou
  • 除了不可变值对象之外,什么时候应该重写 equals() ?

    很明显equals 而且当然hashCode 在处理不可变值对象时很有价值 映射键 需要在包含它们的对象之间进行比较的强类型字段值等 但除了值对象之外 您有多少可能真正拥有两个独立构造的实例并希望它们成为equal 我很难想象一个现实的场景
  • 我可以使用在 DispatcherServlet Context 中声明的 Hibernate Session Factory 而不是 hibernate.cfg.xml 吗?

    在我之前的 Spring MVC 项目中 我使用 Hibernate 作为 JPA 的提供者 我不必创建hibernate cfg xml文件 因为我已经在 Spring DispatcherServlet 上下文文件中声明了 Hibern
  • 为什么 JSON 应该有一个 status 属性

    我偶然发现了一种相当普遍的做法 我什至找到了一个为其命名的网页 但我忘记了名称 并且无法再在谷歌上找到该页面 实践中 来自 REST 服务的每个 JSON 响应都应具有以下结构 status ok data 或者在错误情况下 status
  • DirectX 11 ClearRenderTargetView 恢复透明缓冲区?

    我正在尝试创建一个使用 directx 进行绘制的窗口opaque上面的内容透明的视图 即桌面显示出来 使用 DirectX11 我尝试执行以下操作 但它并没有使背景透明 事实上 我输入的任何不透明度值都会给出完全相同的结果 我在做什么 f
  • Java ConcurrentHashMap 集合的模式

    我在多线程应用程序中常用的数据结构是 ConcurrentHashMap 我想在其中保存一组共享相同键的项目 安装特定键值的第一个项目时会出现此问题 我一直使用的模式是 final ConcurrentMap
  • Flowtype - 字符串与字符串枚举不兼容

    我有一个来自选择输入且类型为字符串的值 但是我想将其传递到函数中 更新语言 接收带有类型别名 Language 我面临的问题是 Flow 只允许我打电话更新语言如果我明确地将我的字符串值与枚举字符串进行比较 并且我想使用像 array in
  • C#:使用指针类型作为字段?

    在 C 中 可以声明具有指针类型成员的结构 或类 如下所示 unsafe struct Node public Node NextNode 它是否安全 呃 暂时忽略那个具有讽刺意味的小unsafe标志 使用这个结构 我的意思是在堆上长期存储