假设我们有结构
struct MyStruct
{
public string a;
}当我们将它赋值给新变量时,字符串会发生什么情况?因此,例如,我们期望在堆栈中复制结构时应该共享字符串。我们使用这段代码来测试它,但是它返回不同的指针:
var a = new MyStruct();
a.a = "test";
var b = a;
IntPtr pA = Marshal.StringToCoTaskMemAnsi(a.a);
IntPtr pB = Marshal.StringToCoTaskMemAnsi(b.a);
Console.WriteLine("Pointer of a : {0}", (int)pA);
Console.WriteLine("Pointer of b : {0}", (int)pB);问题是,何时在堆栈中复制结构并在其中包含字符串,是共享字符串还是重新创建字符串?
更新
我们也尝试过这段代码,它还返回不同的指针:
char charA2 = a.a[0];
char charB2 = b.a[0];
unsafe
{
var pointerA2 = &charA2;
var pointerB2 = &charB2;
Console.WriteLine("POinter of a : {0}", (int)pointerA2);
Console.WriteLine("Pointer of b : {0}", (int)pointerB2);
}发布于 2014-12-04 23:34:02
用于测试它的代码“将托管字符串的内容复制到从非托管COM任务分配器分配的内存块”。根据MSDN的说法。如果随后对StringToCoTaskMemAnsi的任何两个调用都会返回相同的指针,我会感到惊讶。您可以查看两个字符串引用的内存地址,也可以使用调试器分配对象id。或者更简单:object.ReferenceEquals(a.a, b.a);
在您的更新中,您将指向字符变量的堆栈位置,这也不是查找的好方法。在任何情况下,当您将一个字符串分配给另一个字符串时,您只是在复制引用,所以它们应该总是相同的。
发布于 2014-12-04 23:39:17
字符串在存储和引用类型中是不可变的。此外,在您的示例中,字符串"test“是被拘留。因此,无论结构有多少副本,您最终都有多个指向同一个底层存储的指针(除非您通过循环将其复制到一个新的内存块中,这是您设计的示例所做的)。
请放心,只有一个副本,指向多次。
https://stackoverflow.com/questions/27306129
复制相似问题