string s = "Hello world";
char* s2 = s.c_str();
Будет ли s2 выделяться в стеке или в куче?Другими словами ... Нужно ли удалять s2?
Нет, не delete s2
!
s2
в стекеесли приведенный выше код находится внутри функции;если код находится в глобальной области видимости или области имен, то s2
будет находиться в некотором статически размещенном динамически инициализированном сегменте данных.В любом случае, это указатель на символ (который в данном случае оказывается первым 'H'
символом в представлении ASCIIZ текстового содержимого s
).Этот текст сам по себе находится там, где объект s
хотел создать это представление.Реализации могут делать это так, как им нравится, но решающий выбор реализации для std::string
заключается в том, обеспечивает ли она «оптимизацию коротких строк», которая позволяет вставлять очень короткие строки непосредственно в объект s
, и может ли "Hello world"
достаточно коротка, чтобы извлечь выгоду из этой оптимизации:
- , если это так, то
s2
будет указывать на память внутри s
, которая будет распределена в стеке или статически, как объяснено для s2
выше. - в противном случае внутри
s
будет указатель на динамически выделяемую память (free-store / heap), в которой будет отображаться содержимое «Hello world \ 0», адрес которого возвращается .c_str()
, и s2
будет копией этого значения указателя.
Обратите внимание, что c_str()
равно const
, поэтому для компиляции вашего кода вам нужно изменить на const char* s2 = ...
.
Вы не должны delete s2
.Данные, которым s2
баллы по-прежнему принадлежат и управляются объектом s
, будут аннулированы любым вызовом не-1043 * методов s
или s
, выходящими за пределы области.
string s = new string("Hello, mr. heap...");
char* s2 = s.c_str();
Будет ли s2 теперь в куче, поскольку его источник был в куче?
Этот код не компилируется, так как s
не является указателем истрока не имеет конструктора типа string(std::string*)
.Вы можете изменить его на:
string* s = new string("Hello, mr. heap...");
... или ...
string s = *new string("Hello, mr. heap...");
Последний создает утечку памяти и не служит никакой полезной цели, поэтому давайте предположим первый.Тогда:
char* s2 = s.c_str();
... должно стать ...
char* s2 = s->c_str();
Будет ли s2 теперь в куче, так как его источник был в куче?
Да.Во всех сценариях, в частности, если сам по себе s
находится в куче, то:
- , даже если внутри
s
есть буфер оптимизации короткой строки, на который c_str()
дает указатель, он долженбыть в куче, иначе - , если
s
использует указатель для дополнительной памяти для хранения текста, эта память также будет выделена из кучи.
Но, опять же, дажезная наверняка, что s2
указывает на выделенную кучу память, вашему коду не нужно освобождать эту память - это будет сделано автоматически при удалении s
:
string* s = new string("Hello, mr. heap...");
const char* s2 = s->c_str();
...use s2 for something...
delete s; // "destruct" s and deallocate the heap used for it...
Конечно, обычно этолучше просто использовать string s("xyz");
, если вам не нужен срок службы за пределами локальной области, а std::unique_ptr<std::string>
или std::shared_ptr<std::string>
в противном случае.