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

时间:2014-03-06 19:36:01

标签: c# visual-studio-2010

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

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

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

  

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

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

1 个答案:

答案 0 :(得分:14)

  

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

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

  

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

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

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

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

  

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

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

  

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

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

  

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

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

  

我在调试器中没有引号写&nameofstringvariable

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

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

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

  

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

您应该阅读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) { /*...*/ }
  

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

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

  

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

不确定。查看内存窗口中的堆栈帧;其中一些值将是托管地址。