如何在C#中获取字符串的内存地址?

6

请问如何在C#中获取一个string的内存地址?比如在下面这段代码中:

string a = "qwer";

我需要获取变量a的内存地址。


3
为什么你需要那个? - SWeko
11
无论您想做什么,获取变量的内存地址都不是正确的第一步。您能告诉我们您实际要解决的问题吗? - Damien_The_Unbeliever
3
在.NET中,字符串是不可变的。我认为这是你所忽略的一个问题。 - MarcinJuraszek
不,这不是问题。我只是想检查一下a和b的内存地址。 - user2745829
2
那就不要用C#。 - Ritch Melton
显示剩余6条评论
3个回答

7

您需要使用fixed关键字修复内存中的字符串,然后使用char*引用内存地址。

using System;

class Program
{
    static void Main()
    {
        Console.WriteLine(Transform());
        Console.WriteLine(Transform());
        Console.WriteLine(Transform());
    }

    unsafe static string Transform()
    {
        // Get random string.
        string value = System.IO.Path.GetRandomFileName();

        // Use fixed statement on a char pointer.
        // ... The pointer now points to memory that won't be moved!
        fixed (char* pointer = value)
        {
            // Add one to each of the characters.
            for (int i = 0; pointer[i] != '\0'; ++i)
            {
                pointer[i]++;
            }
            // Return the mutated string.
            return new string(pointer);
        }
    }
}

Output

**61c4eu6h/zt1

ctqqu62e/r2v

gb{kvhn6/xwq**


7

让我们来看看你感到惊讶的情况:

string a = "abc";
string b = a;
a = "def";
Console.WriteLine(b); //"abc" why?

ab是字符串的引用。实际涉及的字符串是"abc""def"

string a = "abc";
string b = a;

ab 都是指向同一个字符串 "abc" 的引用。

a = "def";

现在a是一个指向新字符串"def"的引用,但我们没有做任何改变来改变b,所以它仍然指向"abc"
Console.writeline(b); // "abc"

如果我对整数进行相同的操作,你不应该感到惊讶:

int a = 123;
int b = a;
a = 456;
Console.WriteLine(b); //123

比较引用

现在您已经了解到 ab 是引用,您可以使用 Object.ReferenceEquals 比较这些引用。

Object.ReferenceEquals(a, b) //true only if they reference the same exact string in memory

0
你可以调用RtlInitUnicodeString函数,该函数会返回字符串的长度和地址。
using System;
using System.Runtime.InteropServices;

class Program
{
    [StructLayout(LayoutKind.Sequential)]
    public struct UNICODE_STRING
    {
      public ushort Length;
      public ushort MaximumLength;
      public IntPtr Buffer;
    }

  [DllImport("ntdll.dll", CharSet = CharSet.Unicode)]
  static extern void RtlInitUnicodeString(out UNICODE_STRING DestinationString, string SourceString);

  [STAThread]
  static void Main()
  {
    UNICODE_STRING objectName;

    string mapName = "myMap1";
    RtlInitUnicodeString(out objectName, mapName);

    IntPtr stringPtr1 = objectName.Buffer;   // address of string 1


    mapName = mapName + "234";
    RtlInitUnicodeString(out objectName, mapName);

    IntPtr stringPtr2 = objectName.Buffer;  // address of string 2
  }
}

了解C#如何处理字符串可能会很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接