2015-07-02 2 views
2

Я имею string массив инициализирован с буквальным строки, как показано ниже:Массив строковых литералов

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

Таким образом, мы имеем следующие структуры на стеке и Heap:

OnStack: Переменная values холдинг ссылки к массиву строки в куче.

OnHeap: Массив строки, которая ссылается на стек values


Но что будет содержание каждого элемента массива в куче?

  1. Фактические строковые литералы?
  2. Ссылки, указывающие на строковые литералы в пуле пользователя?

Edit: вопрос было указано, как продублировать на this question. Но мой случай отличается в терминах,

  1. Другой вопрос в контексте того, как тип значения в качестве элементов массива ведут себя, что показал, что вопрос проблемка не ясно, каким образом объекты исх/вал типа выделяются на стек/кучу.
  2. В моем вопросе я понимаю, как элементы типа ref/val выделяются в стеке или куче, но я обсуждаю специальный случай, когда объекты являются строковыми литералами. Потому что это должно иметь дело с международным пулом и GC.
+0

Возможный дубликат [Как массив типов значений, хранящихся в кучи объектов .NET?] (Http: // stackoverflow .com/questions/5087987/how-is-an-array-of-value-types-stored-in-net-object-heap) –

ответ

2

В данном конкретном случае, учитывая Microsoft .NET CLR (это важно только для позиции values, если в стеке или куче), у вас будет 5 ссылок на 5 объектов.

Чтобы быть точным, у вас есть массив из string s (1 объект), то есть массив ссылок на string (еще 4 объекта).

Пять ссылки:

  • values (в данном случае на стеке)
  • 4x ссылки на 4x интернировано string с (содержащиеся в куче, в string[] массиве)

Пять объектов:

  • массив из string[], содержащиеся в куче
  • 4x string объекты, которые интернированы, но они по-прежнему являются полноценной object с, единственное отличие состоит в том, что GC никогда не будет освобождать их (если их AppDomain не выгружается)

Таким образом, это

Ссылки, указывающие на строковые литералы в пуле пользователя?

+0

В качестве следствия (для соответствия): если бы у меня было 4 нелитеральных строковых переменных, инициализирующих массив строк, фактические строки будут элементами массива? – Marshal

+1

@NirajDoshi Нет, 'string []' array - массив ссылок на 'string', ** always **. Не существует практической разницы между интернированной «строкой» и неинтерминированной «строкой», отличной от времени ее жизни, и что некоторые статические методы 'string' (' Intern' и 'IsInterned') могут использоваться для извлечения интернированной строки '/ проверить, запущена ли' строка'. – xanatos

2

Это совершенно то же самое, как если бы вы создаете:

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

И создать экземпляр этого:

class MyArray instance = new MyArray(); 

Это приведет к выделению памяти для MyArray например, и ряд смежных областей на куче. Он также создает ссылку, указывающую на этот объект, и ссылки на все связанные поля. То же самое с массивом, за исключением того, что вы используете ссылки на поля, обращаясь к индексатору массива, а затем совершаете прямые звонки, например, instance.first

+0

Хороший пример, который дает более четкое представление о том, как ведут себя массивы. Но мой вопрос еще один шаг вперед, как в строковых литералах. Поскольку строковые литералы ведут себя специально в .net CLR – Marshal

+1

@NirajDoshi: для вашего шага вперед вы должны знать, как ведет себя пул строк. Если он найдет какое-либо значение в таблице, он просто вернет ссылочный адрес этого значения, а не создаст новую запись с таким же значением. Это второй, о котором вы просите. –

Смежные вопросы