如何在Visual Studio 2010 C#中获取字符串的堆栈内存地址#

han*_*y88 5 c# visual-studio-2010

我目前正在大学攻读计算机科学课程,最近我们看到了如何在调试器中使用&和*获取变量的内存地址.我的老师告诉我,本地值类型变量在堆栈中,引用类型在堆中.但他也告诉堆栈应该包含字符串在堆中的地址.

我不知道你是否明白我想说的是什么,但它应该是可能的,因为我在他给我们的笔记中看到了它.但当他试图向我们展示时,它没有用,他不知道为什么.

我想知道该怎么做但是当我尝试时总是收到此错误消息:

不能获取地址,获取大小,或声明指向托管类型('string')的指针.

&nameofstringvariable在调试器中没有引号.我想了解事情是如何运作的,我在谷歌搜索这个问题的时间,但我从来没有找到解决方案.尝试使用unsafe代码并且无法正常工作.

Eri*_*ert 15

我目前正在大学攻读计算机科学课程,我们最近看到了如何在调试器中使用&和*获取变量的内存地址

&为您提供C#中非托管类型固定变量的地址; 结果是一个指针. *取消引用指针并将其转回变量,它不会为您提供变量的地址.

我的老师告诉我,本地值类型变量在堆栈中,引用类型在堆中.

让我们确保我们做对了,因为这非常令人困惑.

如果已知其生命周期很短,则无论变量是包含值类型的实例还是对堆的引用,局部变量都会进入堆栈.请注意,局部变量的生命周期不需要很短!考虑例如λ的封闭外部变量; 它的生命周期与关联的委托相同,它不是短的,所以它不能进入​​堆栈.

引用类型的实例在堆上,因此与引用类型实例关联的变量在堆上.但参考不一定是.参考类型和参考类型的实例与蛋糕和烹饪书籍不同.

他还告诉堆栈应该包含字符串在堆中的地址.

正确; 如果有一个短期变量或值是对堆上字符串的引用,那么该变量或值将存储在堆栈中.请注意,这是一个托管引用,而不是非托管引用.

但当他试图向我们展示时,它没有用,他不知道为什么.

也许他应该是那时问这个问题的人.

我想知道该怎么做但是当我尝试时总是收到此错误消息:

正确.您不能像这样操纵托管引用.

&nameofstringvariable在调试器中没有引号

这将为您提供包含引用的变量的地址.它没有给你参考!

你看,你有一张纸上面写着"123芝麻街".这是一个房子的参考.你把那张纸放在宾夕法尼亚大道1600号.当你要求提供这张纸的地址时,它位于宾夕法尼亚大道1600号,而不是123芝麻街.

无论如何,获取托管类型变量的地址是不合法的.

我想了解事情是如何运作的,我在谷歌搜索这个问题的时间,但我从来没有找到解决方案

您应该阅读C#规范的第18章.小心.

你还应该阅读我关于这个主题的所有文章,并让你的老师在你的时候阅读它们.

http://blogs.msdn.com/b/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx

http://blogs.msdn.com/b/ericlippert/archive/2009/04/27/the-stack-is-an-implementation-detail.aspx

http://blogs.msdn.com/b/ericlippert/archive/2009/05/04/the-stack-is-an-implementation-detail-part-two.aspx

http://blogs.msdn.com/b/ericlippert/archive/2010/09/30/the-truth-about-value-types.aspx

http://blogs.msdn.com/b/ericlippert/archive/2010/10/11/debunking-another-myth-about-value-types.aspx

http://blogs.msdn.com/b/ericlippert/archive/2012/01/16/what-is-the-defining-characteristic-of-a-local-variable.aspx

所以现在你没有问过一些问题:

所以不可能获得对字符串的托管引用作为指针?

是.在C#语言中,将托管引用作为指针是不可能.

但我能做到这一点!

string str = "Hello World";
fixed (char* p = str) { /*...*/ }
Run Code Online (Sandbox Code Playgroud)

现在我有一个指向字符串中第一个字符的指针.这不是一回事吗?

当然不是!这是一个指向a的非托管指针char,而不是指向a的托管指针string.面包盒中第一片面包的位置与面包盒的位置不同.

是否可以在调试器中获取与字符串关联的托管地址?

当然.查看内存窗口中的堆栈帧; 其中一些值将是托管地址.

  • @ handyguy88:不客气.大多数人不正确地学习这些东西然后必须回去并正确地重新学习它(或者一辈子都相信错误.)现在是你正确学习所有这些东西的好时机. (2认同)
  • @EricLippert 非常好!我会一有机会就把它们全部读完。顺便说一下,您的网站就像开发人员的绿洲:) 当我读到这么好的文章时,我总是告诉自己我希望我的英语更好......我希望我能正确地内化它们。再次感谢您处理链接。 (2认同)