Так, я желаю надеть лучшее схватывание, как работают строковые литералы в C++. Я главным образом обеспокоен ситуациями, где Вы присваиваете адрес строкового литерала к указателю и раздаете его. Например:
char* advice = "Don't stick your hands in the toaster.";
Теперь позволяет, говорят, что я просто раздаю эту строку путем копирования указателей на время программы. Несомненно, это - вероятно, не хорошая идея, но мне любопытно, что на самом деле продолжилось бы негласно.
Для другого примера скажем, мы делаем функцию, которая возвращает строковый литерал:
char* foo()
{
// function does does stuff
return "Yikes!"; // somebody's feeble attempt at an error message
}
Теперь позволяет, говорят, что эта функция вызывается очень часто, и строковый литерал только используется приблизительно половина времени, которым это называют:
// situation #1: it's just randomly called without heed to the return value
foo();
// situation #2: the returned string is kept and used for who knows how long
char* retVal = foo();
В первой ситуации, что на самом деле происходит? Строка просто создается, но не используется и никогда не освобождается?
Во второй ситуации строка собирается сохраняться, пока пользователь находит потребность в ней? Что происходит, когда не необходимо еще..., чтобы память была освобождена затем (предполагающий, что ничто больше не указывает на то пространство)?
Не понимайте меня превратно, я не планирование использования строковых литералов как это. Я - планирование использования контейнера для контроля над моими строками (вероятно, станд.:: строка). Я главным образом просто желаю знать, могли ли эти ситуации вызвать проблемы или для управления памятью или повредили данные.
Строковые литералы имеют тип const char [N]
(где N
- длина + 1) и статически размещены. Вам не нужно беспокоиться о проблемах с памятью; если в вашей программе используется строка, она обрабатывается за вас и находится где-то в памяти программы (обычно только для чтения).
То есть это «то же самое»:
static const char str[] = "a string";
"a string"
Когда вы указываете строковый литерал, вы указываете на первый символ в массиве. Фактически, поскольку типом является const char []
, безопасно указывать на него только через const char *
. Преобразование строкового литерала в char *
устарело и небезопасно.
// the "same"
static const char str[] = "a string";
const char* strPtr = str; // decays
const char* s1 = "a string";
char* s2 = "a string"; // allowed, implicit const_cast
*s1 = 'A'; // not allowed, it's const
*s2 = 'B'; // allowed, it's not const (but leads to undefined behavior)
Во-первых, объявите возвращаемое значение foo как const, потому что строковые литералы - это константы, которые нельзя изменить, не вызывая ужасного «неопределенного поведения». Затем это заставит любые указатели, которые используют возвращаемое значение foo, также быть объявлено как const, и потенциально ограничит ущерб, который может быть (обычно непреднамеренно) нанесен. Строковые литералы хранятся в «текстовой» области двоичного исполняемого файла - они не создаются как таковые во время выполнения.