Case 1
string s1 = "ABCD";
string
обрабатывает выделение памяти для хранения "ABCD"
для вас. Деструктор string
будет вызван автоматически, когда s1
выйдет из области видимости, что освободит память, выделенную string
.
s1 = "EFGH";
Оператор назначения копирования string
перезапишет сохранение памяти "ABCD"
с "EFGH"
.
Случай 2
char* val = "ABCD";
val = "EFGH";
Фред Ларсон ответил на этот вопрос в комментариях выше, вы просто переназначаете указатель на строку stati c. Стек будет выделять память только для указателя (не для данных), и указатель будет автоматически освобожден, когда val
выйдет из области видимости.
Случай 3
string s1 = "ABCD";
string s2 = s1;
s2
выделит память и скопирует s1
. Реализация копирования при записи оператора присваивания копии будет выделять и копировать память только в случае мутации s2
. Однако начиная с C ++ 11 кажется, что реализации COW std::string
больше не разрешены ( Легальность реализации COW std :: string в C ++ 11 ).
Case 4
Вот пример сценария, когда вам делать нужно беспокоиться об освобождении выделенной памяти.
Вы можете использовать это, если вам нужно string
, чтобы пережить область, в которой он был создан. (На практике обычно следует избегать такого подхода. См. Случай 5 ниже.)
string* s1 = new string("ABCD");
delete s1;
В этом примере string
все еще внутренне управляет памятью для хранения "ABCD"
, но указатель string
выделен в куче, а деструктор string
не будет вызван, когда s1
выйдет из области видимости. В этом случае вы несете ответственность за использование delete
для обеспечения очистки памяти, когда s1
больше не требуется.
Случай 5
shared_ptr<string> s1 = make_shared<string>("EFGH");
shared_ptr
обычно путь к go против new
и delete
. Общие указатели предотвращают много утечек памяти из-за ошибок программирования. shared_ptr
обрабатывает delete
для вас и использует подсчет ссылок, чтобы поддерживать string
до тех пор, пока не будет уничтожена последняя ссылка.