gpt4 book ai didi

c# - 持久性内存困惑

转载 作者:行者123 更新时间:2023-11-30 21:53:43 25 4
gpt4 key购买 nike

我试图理解 C# 中的持久内存,但不知道为什么这段代码没有保留其中一个函数所做的更改。

using System;
using System.Runtime.InteropServices;

public class Test2
{
public struct value
{
public int sz;
}

public static void Main(string[] args)
{
one foo1 = new one(one_full);
two foo2 = new two(two_full);
make_calls(foo1, foo2);
}

public delegate void one(IntPtr ctx);
public static void one_full(IntPtr ctx)
{
/* set sz and see if persists */
GCHandle gch = GCHandle.FromIntPtr(ctx);
value val = (value)gch.Target;

val.sz = 6;
Console.WriteLine("Changed sz to be 6");
}

public delegate void two(IntPtr ctx);
public static void two_full(IntPtr ctx)
{
GCHandle gch = GCHandle.FromIntPtr(ctx);
value val = (value)gch.Target;

Console.Write("sz is = ");
Console.WriteLine(val.sz);
}

public static void make_calls(one f_one, two f_two)
{
value test = new value();
test.sz = 0;

IntPtr ptr = GCHandle.ToIntPtr(GCHandle.Alloc(test));
f_one(ptr);
f_two(ptr);
}
}

我知道它在最后缺少 free 但这只会导致困惑的内存管理....我正在寻找是否有人可以帮助我并解释为什么 sz 在第二个函数被称为...

运行时的输出是:

Changed sz to be 6
sz is = 0

最佳答案

这都是因为value 是一个struct

GCHandle.Alloc 接受一个 object 参数,因此如果您传递一个 struct,它必须被装箱。

以后用的时候

value val = (value)gch.Target;

它必须拆箱,所以它的副本 存储在 val 中。您以后所做的任何修改都是在副本上进行的,而不是在盒装的 struct 上进行的。

它与 GCHandle 无关,它是值类型 (struct) 在 C# 中的工作方式。这就是为什么建议使值类型不可变。

关于c# - 持久性内存困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33713541/

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