为什么字符串指针位置不同?

Moh*_*deh 4 c# pointers unsafe-pointers string-interning

为什么每次运行应用程序时字符串指针的位置都不同,当我使用StringBuilder时,当我声明变量时,它是相同的?

void Main()
{
    string str_01 = "my string";
    string str_02 = GetString();
    unsafe 
    {
        fixed (char* pointerToStr_01 = str_01)
        {
            fixed (char* pointerToStr_02 = str_02)
            {
                Console.WriteLine((Int64)pointerToStr_01);
                Console.WriteLine((Int64)pointerToStr_02);
            }
        }
    }
}

private string GetString()
{
    StringBuilder sb = new StringBuilder();
    sb.Append("my string");

    return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)

输出:

40907812
178488268

下次:

40907812
179023248

下次:

40907812
178448964

You*_*elf 12

str_01持有对常量字符串的引用.StringBuilder但是,动态构建字符串实例,因此返回的字符串实例与具有相同内容的常量字符串的引用不同.System.Object.ReferenceEquals()会回来的false.

由于它str_01是对常量字符串的引用,因此其数据可能存储在可执行文件的数据部分中,该部分始终在应用程序虚拟地址空间中获得相同的地址.

编辑:

当您使用PE.Explorer或类似软件打开已编译的.exe文件时,您可以以UTF-8编码查看"my string"文本.它存在于文件的.data部分中,包括首选的虚拟地址,其中该部分应加载到进程虚拟内存中.

然而,我无法重现在str_01应用程序的多次运行中具有相同地址,可能是因为我的x64 Windows 8.1执行地址空间布局随机化(ASLR).因此,所有指针在应用程序的多次运行中都会有所不同,甚至是那些直接指向加载的PE部分的指针.