Насколько безопасный и надежный Строковые литералы C++?

Так, я желаю надеть лучшее схватывание, как работают строковые литералы в 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();

В первой ситуации, что на самом деле происходит? Строка просто создается, но не используется и никогда не освобождается?

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

Не понимайте меня превратно, я не планирование использования строковых литералов как это. Я - планирование использования контейнера для контроля над моими строками (вероятно, станд.:: строка). Я главным образом просто желаю знать, могли ли эти ситуации вызвать проблемы или для управления памятью или повредили данные.

7
задан Tim Leaf 29 April 2010 в 20:53
поделиться

2 ответа

Строковые литералы имеют тип 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)
22
ответ дан 6 December 2019 в 07:50
поделиться

Во-первых, объявите возвращаемое значение foo как const, потому что строковые литералы - это константы, которые нельзя изменить, не вызывая ужасного «неопределенного поведения». Затем это заставит любые указатели, которые используют возвращаемое значение foo, также быть объявлено как const, и потенциально ограничит ущерб, который может быть (обычно непреднамеренно) нанесен. Строковые литералы хранятся в «текстовой» области двоичного исполняемого файла - они не создаются как таковые во время выполнения.

1
ответ дан 6 December 2019 в 07:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: