3

所以我知道它interior_ptr<typename>可以用来操作结构数组,就像在 C♯ 中使用fixed语句一样,但它不会修复堆上的数组并让垃圾收集移动它。这很好,因为我不想妨碍垃圾收集器有效工作。但是,垃圾收集器在单独的线程上运行,当它处于活动状态时,所有其他线程都会停止,而堆上的对象会被压缩。

假设我有以下代码:

interior_ptr<unsigned char> sourceBufferPtr = reinterpret_cast<interior_ptr<unsigned char>>(&sourceBuffer[0]) + sourceOffset;

代码应该像这样运行,例如:

  1. &sourceBuffer[0]返回数组中第一项的地址:32。
  2. sourceOffset: 8。
  3. reinterpret_cast<interior_ptr<unsigned char>>(&sourceBuffer[0])将地址转换为interior_ptr<unsigned char>,然后将其添加到sourceOffset.
  4. sourceBufferPtr应该等于……
    • 如果垃圾收集器没有移动数组,则为 40。
    • 如果垃圾收集器将数组移动到像 16 这样的位置,则为 24。
    • 如果垃圾收集器在第 3 步和第 4 步之间移动了数组,则为 40,因此在第 3 步之后数组的位置将更新为 16,但分配给的结果sourceBufferPtr仍然是 40。

我是否正确假设垃圾收集器可以在步骤 3 和 4 之间停止线程并可能分配错误的值,sourceBufferPtr或者公共语言运行时是否知道如何确保整个语句是原子的/值是正确的?做什么安全的interior_ptr<typename>

4

1 回答 1

3

我是否正确假设垃圾收集器可以在步骤 3 和 4 之间停止线程并可能为 sourceBufferPtr 分配错误的值?

是的,因为您的代码不正确。通过在获得指向数组元素的未管理指针后使用 reinterpret_cast,您为 GC 引入了使指针无效的机会窗口。您需要像这样不间断地使用interior_ptr:

interior_ptr<unsigned char> bufferPtr = &sourceBuffer[0];
interior_ptr<unsigned char> sourceBufferPtr = bufferPtr + sourceOffset;

在这个新代码中,只有interior_ptr's。甚至第二个赋值右侧的临时变量也是一个 internal_ptr。

于 2012-05-19T21:57:00.640 回答