C# 如何在C中显示引用的实际值#

C# 如何在C中显示引用的实际值#,c#,C#,我正在学习更多关于C#的知识,我想知道如何显示引用的实际值或结构的地址。我要寻找的是类似于以下C代码的东西: int i; printf("int i resides at memory location %x",&i); 我知道这不能用C#来完成。NET可以随意移动存储器的各个部分,因此变量的地址充其量只能是暂时的。在不安全的上下文中,这将在C#中起作用: 我不知道它是否可以在安全的环境下完成,或者,如果可以,如何完成(我怀疑它不能)。尽管在某些环境下可以这样做,但

我正在学习更多关于C#的知识,我想知道如何显示引用的实际值或结构的地址。我要寻找的是类似于以下C代码的东西:

    int i; 
    printf("int i resides at memory location %x",&i);

我知道这不能用C#来完成。NET可以随意移动存储器的各个部分,因此变量的地址充其量只能是暂时的。

不安全的
上下文中,这将在C#中起作用:

我不知道它是否可以在安全的环境下完成,或者,如果可以,如何完成(我怀疑它不能)。

尽管在某些环境下可以这样做,但结果基本上没有意义。正如已经注意到的,或者至少,他们不必如此。因此,您正在尝试的内容,即使有效,也不能保证在所有实现中都能实现,而且通常也不是特别有用。如果不进行pin,则值不可靠,如果进行pin,则会更改正在报告的内容


真的,你应该在语言之外使用不同的工具。。。例如,windbg+SOS。

在一个非平凡的应用程序中,这会是常数吗?我会假设,如果它存活到第二代,它可能是常数,但在此之前它可以移动。但我从未尝试过。C#spec的第18.3节对此进行了彻底的解释。查看“固定”状态。它归结为指针是否正在查看GC认为可移动的东西。发布的代码将显示堆栈的内容,而不是GC堆。创建指向引用类型的指针需要先固定它。这是Heisbergian,您现在不再查看堆的正常布局。使用sos.dll调试器扩展名!根据Gregory的回答,默认情况下GC将在修剪死对象后压缩堆以整合可用空间。因此,除非您将对象标记为固定(通常只有在需要使用非托管代码交换对象/指针时才建议这样做),否则您的对象可以四处移动。您试图实现什么?你想学什么?有可能你不能用这种方式来学习它。我想看看多维字符串数组是如何存储在堆上的。我是一个嵌入式的人,喜欢看事情的进展。你可以查看Windbg的SOS。转储进程内存并查看事情的布局。还有一些关于.NET内存管理的讨论。此列表:相当全面。感谢GrayWizardx,实际上我可以通过在VisualStudio的监视窗口中使用C地址操作符来获取所需的信息。我只是好奇是否有一种方法可以用代码来实现。好奇的人想知道。
int i = 10;
int *ptr = &i;
Console.WriteLine((int)ptr);