2014-12-04 2 views
0

Допустим, мы имеем структуруСтрока внутри поведения структуры

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); 

Вопрос в том, когда копируются Структуры в стеке и есть строка внутри же она разделяет строку или строка воссоздана?

[UPDATE]

Мы также попробовали этот код, он возвращает различные указатели, а также:

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); 
    } 

ответ

3

код, который вы используете, чтобы проверить его «Копирует содержимое управляемой строки к блоку памяти, выделенной из неуправляемого распределителя задач COM ». согласно MSDN. Я был бы удивлен, если бы любые два последующих обращения к StringToCoTaskMemAnsi вернули бы тот же указатель. Вы можете посмотреть адрес памяти двух строковых ссылок или назначить идентификатор объекта с помощью отладчика. Или проще: object.ReferenceEquals(a.a, b.a);

В своем обновлении вы указываете на расположение стека переменных символов, также не являетесь хорошим способом узнать. В любом случае вы просто копируете ссылку, когда вы назначаете строку другой строке, поэтому они всегда должны быть одинаковыми.

+0

см. Мое обновление, пожалуйста, имеет смысл? –

+0

«В любом случае вы просто копируете ссылку, когда вы назначаете строку другой строке, поэтому они всегда должны быть одинаковыми», но она возвращает разные указатели на выходе. –

+0

@JevgenijNekrasov, как вы его протестируете, ** всегда ** обеспечивает различные указатели, независимо от ввода. Посмотрите на последнее предложение моего первого абзаца в ответе, либо выполните проверку, используя «ReferenceEquals», либо используйте отладчик VS. – Bas

0

Строки неизменяемы при хранении и ссылочном типе. Кроме того, в вашем примере строка «test» равна interned. Поэтому, независимо от того, сколько копий структуры вы делаете, у вас в конечном итоге есть несколько указателей на одно и то же хранилище поддонов (если только вы не перейдете к копиям, чтобы скопировать его в новый блок памяти, который делаются на ваши надуманные примеры)

Будьте уверены, что существует только одна копия, указываемая на несколько раз.

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