【问题标题】:Array with literal strings带有文字字符串的数组
【发布时间】:2015-09-19 14:05:04
【问题描述】:

我有一个string 数组,用下面的文字字符串初始化:

public static void Main()
{
     string[] values = new string[] { "Cat", "Dog", "Mouse", "Rat" };
}

所以我们在堆栈和堆上有以下结构:

OnStack:一个变量values持有对堆上字符串数组的引用。

OnHeap:栈上values引用的字符串数组


但是堆上数组的每个元素的内容是什么?

  1. 实际的字符串文字?
  2. 指向实习池中字符串文字的引用?

编辑:该问题被指出为与this question 重复。但我的情况不同

  1. 另一个问题是关于值类型作为数组元素如何表现的上下文,这表明问题提出者不清楚如何在堆栈/堆上分配 ref/val 类型对象。
  2. 在我的问题中,我很清楚如何在堆栈或堆上分配 ref/val 类型的元素,但我正在讨论对象是字符串文字时的特殊情况。因为那必须处理实习生池和 GC。

【问题讨论】:

标签: c# arrays .net string heap-memory


【解决方案1】:

在这种特殊情况下,考虑到 Microsoft .NET CLR(这仅对 values 的位置很重要,如果在堆栈或堆中),您将有 5 个对 5 个对象的引用。

准确地说,您有一个strings(1 个对象)的数组,即对string(另外4 个对象)的引用数组。

五个参考是:

  • values(在本例中位于堆栈上)
  • 4x 引用 4x interned strings(包含在堆上,在 string[] 数组中)

这五个对象是:

  • string[] 的数组,包含在堆中
  • 4x string 被实习的对象,但它们仍然是完全成熟的 objects,唯一的区别是 GC 永远不会释放它们(除非它们的 AppDomain 被卸载)

原来如此

指向实习池中字符串文字的引用?

【讨论】:

  • 作为推论(符合):如果我有 4 个非文字字符串变量初始化字符串数组,实际的字符串将是数组的元素?
  • @NirajDoshi 不,string[] 数组是对string 的引用数组,总是。实习生string 和非实习生string 之间没有实际区别,除了它的生命周期和一些静态string 方法(InternIsInterned)可用于检索实习生@987654338 @/检查 string 是否被实习。
【解决方案2】:

这和你创造的完全一样:

class MyArray
{
     string first;
     string second; 
     string third;
     ... more strings
}

并创建它的实例:

class MyArray instance = new MyArray();

这将导致 MyArray 实例的内存分配以及堆上相关字段的数量。它还创建指向该对象的引用以及对所有相关字段的引用。与数组相同,只是您通过访问数组索引器来引用字段,而不是像instance.first这样直接调用

【讨论】:

  • 很好的例子,可以更清楚地了解数组的实际行为方式。但就字符串文字而言,我的问题更进一步。因为字符串文字在 .net CLR 中的行为特别
  • @NirajDoshi:为了让您领先一步,您必须了解字符串实习生池的行为方式。如果它在表中找到任何值,它将只返回该值的引用地址,而不是创建具有相同值的新条目。这是您要的第二个。
猜你喜欢
  • 2015-09-11
  • 2020-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
相关资源
最近更新 更多