этот объект в стеке или куче?

.net c++-cli heap-memory

108 просмотра

1 ответ

В C ++ / CLI следующие 2 одинаковы или различны?

System::String ^source("Hello World");

System::String ^source= gcnew System::String("Hello World");

Первый в стеке, а второй в куче?
Или они оба в куче?
Я считаю, что объекты .Net имеют только ссылки, которые не могут быть созданы в стеке, в отличие от C ++. Может кто-нибудь объяснить, пожалуйста?

Автор: Ahmed Источник Размещён: 08.11.2019 11:11

Ответы (1)


7 плюса

Строка не сохраняется ни в стеке, ни в куче. История немного запутанная.

Обычно полезный способ думать об этом состоит в том, что объекты ссылочного типа всегда хранятся в куче GC. Очень похоже на C ++ (он же std :: string), объекты переменной длины, такие как строки, должны использовать свободное хранилище для выделения правильного объема памяти. По модулю возможная микрооптимизация в std :: string, которая может хранить очень короткие строки внутри объекта std :: string. Но обычно сам объект std :: string может быть размещен в стеке, а содержимое строки - в куче. Точно так же, как sourceв стеке, просто простой указатель, который сборщик мусора может найти обратно.

Язык C позволяет хранить содержимое строки в стеке, но вы должны заранее определить необходимую длину строкового буфера. Запуская тысячи вредоносных атак, переполнение строкового буфера является стандартной техникой, чтобы связываться со стековым фреймом программы и изменять возвращаемое значение функции. Не. NET способ. Компилятор языка AC не должен делать это таким образом, он просто делает это очень часто.

Но это не так просто в приведенном вами примере. Между операторами нет никакой разницы, содержимое строки не выделяется ни в стеке, ни в куче. CLR сильно микрооптимизирован, чтобы воспользоваться преимуществами спецификации CLI, стандарта, который описывает, как строки должны вести себя в соответствующей реализации CLR.

Он использует то свойство, что строковые объекты являются неизменяемыми. Это разрешает оптимизацию, называемую интернированием . Строковый объект выглядит и ведет себя так, как будто он хранится в куче GC. Но на самом деле это не так, содержимое объекта непосредственно считывается из отображенного в памяти образа сборки. Хранится в «куче блобов» в метаданных сборки. GC просто игнорирует их, когда сталкивается с таким строковым объектом во время сбора. Очень похоже на поведение строковых литералов на языке Си. За исключением ошибки, которая вызвала миллиард сбоев (строковый литерал char*вместо того, const char*каким он должен быть), вы никогда не сможете случайно записать строковый литерал благодаря гарантии неизменности.

Автор: Hans Passant Размещён: 20.08.2016 12:13
Вопросы из категории :
32x32