gpt4 book ai didi

c# - 对是否使用 fixed with unsafe code 和 stackalloc 的困惑

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

下面有一段代码,其中一行被注释掉了。 CreateArray 方法中发生的事情与注释掉的行所做的事情相同。我的问题是,为什么当行 b->ArrayItems = d 未被注释时它可以工作,但在被注释掉时返回垃圾?我认为我不必“修复”任何东西,因为所有信息都是不受管理的。这个假设不正确吗?

class Program
{
unsafe static void Main(string[] args)
{
someInstance* b = stackalloc someInstance[1];
someInstance* d = stackalloc someInstance[8];

b->CreateArray();
// b->ArrayItems = d;

*(b->ArrayItems)++ = new someInstance() { IntConstant = 5 };
*(b->ArrayItems)++ = new someInstance() { IntConstant = 6 };

Console.WriteLine((b)->ArrayItems->IntConstant);
Console.WriteLine(((b)->ArrayItems - 1)->IntConstant);
Console.WriteLine(((b)->ArrayItems - 2)->IntConstant);
Console.Read();
}
}

public unsafe struct someInstance
{
public someInstance* ArrayItems;
public int IntConstant;
public void CreateArray()
{
someInstance* d = stackalloc someInstance[8];
ArrayItems = d;
}
}

最佳答案

My question is why does it work when the line is uncommented, but return garbage when commented out.

注释行是掩盖由 CreateArray 引起的错误。将其注释掉会暴露该错误。但无论如何,错误都存在。

正如规范明确指出的:

All stack allocated memory blocks created during the execution of a function member are automatically discarded when that function member returns.

CreateArray 函数分配一个 block ,您存储一个指向该 block 的指针,该 block 被丢弃,现在您有一个指向垃圾 block 的指针。您需要永远不要存储指向堆栈分配 block 的指针,以便在 block 无效后可以访问存储。如果您需要存储对 block 的引用,请在堆上分配 block ,并记得在完成后释放它。

请记住,在不安全的代码中您需要完全理解关于托管内存模型的一切 一切。如果您不了解有关托管内存的所有内容,请不要编写不安全的代码。

也就是说,让我们来解决您似乎比较困惑的问题,即“您什么时候必须修复内存才能获得指针?”答案很简单。 当且仅当它是可移动的内存时,您才必须修复它。 固定将可移动的内存转变为不可移动的内存; 这就是修复的目的

你只能获取不动产的地址;如果你获取可移动的东西的地址并且它移动那么显然地址是错误的。您需要确保在获取其地址之前内存不会移动,并且您需要确保在它再次变为可移动后不再使用该地址。

关于c# - 对是否使用 fixed with unsafe code 和 stackalloc 的困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3339511/

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