gpt4 book ai didi

c# - 'fixed' 的要求在 C# 中似乎不一致

转载 作者:行者123 更新时间:2023-11-30 13:48:17 30 4
gpt4 key购买 nike

我有一个包含字段的有序结构..

[StructLayout(LayoutKind.Explicit)]
public unsafe struct RunBlock_t {
[System.Runtime.InteropServices.FieldOffset(0)] public fixed byte raw[512];
}

如果我在一个函数中声明它并想使用指针,它工作正常..

{
RunBlock_t r = new RunBlock_t();
for (int i=0; i<512; i++) r.raw[i]=0;
}

但是如果我在范围外声明变量,它需要一个固定的实现

RunBlock_t r;
{
r = new RunBlock_t();
fixed (byte* ptr = r.raw) for (int i=0; i<510; i++) ptr[i]=0;
}

为什么会出现这种行为差异?

--- 已编辑 -----

只是想再次声明任何其他排列均无效。

    unsafe void foo() {
RunBlock_t r = new RunBlock_t();
fixed (byte* ptr = r.raw) for (int i = 0; i < 512; i++) ptr[i] = 0;
}

生成您不能使用固定语句获取已固定表达式的地址并且不编译。

    RunBlock_t r;
unsafe void foo() {
r = new RunBlock_t();
for (int i=0; i<512; i++) r.raw[i]=0;
}

生成 您不能使用包含在不固定表达式中的固定大小缓冲区。尝试使用 fixed 语句。 并且无法编译。

最佳答案

不幸的是,您稍微混淆了这个问题。如果我从问题中复制完全,那么这很好用:

    {
RunBlock_t r = new RunBlock_t();
for (int i = 0; i < 512; i++) r.raw[i] = 0;
}

还有这个:

    RunBlock_t r;
{
r = new RunBlock_t();
fixed (byte* ptr = r.raw) for (int i = 0; i < 510; i++) ptr[i] = 0;
}

加注:

You cannot use the fixed statement to take the address of an already fixed expression

如果我们删除 fixed,它会起作用。

您应该显示的是函数签名,即

RunBlock_t r;
unsafe void Bar()
{
{
r = new RunBlock_t();
fixed (byte* ptr = r.raw) for (int i = 0; i < 510; i++) ptr[i] = 0;
}
}

现在意思更清楚了。您会看到,当您使用 fixed 访问值中的固定缓冲区时,您实际上并没有修复缓冲区,也没有修复;您实际上修复的是包含对象,即具有 r 字段的对象。这是为了防止 GC 在堆栈上移动它,如果我们当时将它作为指针访问,那将是不好的。在我们上面的例子中,我们的表达式实际上是fixed (byte* ptr = this.r.raw),被固定的是:this

如果我们有一个结构作为本地,这是不同的。本地人在堆栈;它们(正如之前的消息所暗示的那样)已经修复;堆栈永远不会被 GC 重新定位。

所以:

  • 如果你有一个结构作为局部变量,你不需要使用fixed - 你只是直接访问它作为一个指针(通过ldloca)<
  • 如果您有一个是对象中的字段的结构,您需要使用fixed,在操作期间将对象固定到位<
  • 如果您将引用传递给结构(即ref RunBlock_t 参数),那么您必须使用fixed < strong>以防万一它是对象上的字段;如果引用结果解析为堆栈,那么它不需要做任何事情
  • 请注意,此处关于“对象上的字段”的所有内容同样适用于“数组中的值”,即如果我们谈论的是 someArray[8](因为您可以操纵原位阵列)

关于c# - 'fixed' 的要求在 C# 中似乎不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13095238/

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