Да, время жизни локальной переменной находится в области ( {
, }
), в которой она создана.
Локальные переменные имеют автоматическое или локальное хранилище. Автоматически, потому что они автоматически уничтожаются, когда заканчивается область, в которой они созданы.
Однако здесь имеется строковый литерал, который выделяется в памяти только для чтения, определенной в реализации. Строковые литералы отличаются от локальных переменных и остаются активными на протяжении всего времени существования программы. Они имеют статическую продолжительность [Ref 1] срока службы.
Предупреждение!
Однако обратите внимание, что любая попытка изменить содержимое строкового литерала является неопределенным поведением (UB). Пользовательским программам не разрешается изменять содержимое строкового литерала.
Следовательно, всегда рекомендуется использовать const
при объявлении строкового литерала.
const char*p = "string";
вместо,
char*p = "string";
Фактически, в C ++ не рекомендуется объявлять строковый литерал без символа, const
хотя и не в C. Однако объявление строкового литерала с a const
дает вам преимущество, заключающееся в том, что компиляторы обычно выдают предупреждение, если вы попытаетесь изменить строковый литерал в второй случай.
Пример программы :
#include<string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[]="Sample string";
strcpy(str1,source);
strcpy(str2,source);
return 0;
}
Вывод:
cc1: предупреждения обрабатываются как ошибки
prog.c: В функции 'main':
prog.c: 9: error: передача аргумента 1 из 'strcpy' отбрасывает квалификаторы из целевого типа указателя
Обратите внимание, что компилятор предупреждает о втором случае, но не о первом.
Чтобы ответить на вопрос, который задают здесь несколько пользователей:
В чем дело с целочисленными литералами?
Другими словами, действителен ли следующий код?
int *foo()
{
return &(2);
}
Ответ: нет, этот код недействителен. Он неправильно сформирован и приведет к ошибке компилятора.
Что-то вроде:
prog.c:3: error: lvalue required as unary ‘&’ operand
Строковые литералы являются l-значениями, то есть: вы можете взять адрес строкового литерала, но не можете изменить его содержимое.
Тем не менее, любые другие литералов ( int
, float
, char
, и т.д.) являются г-значения (стандарт С использует термин значение выражения для них) и их адреса не могут быть приняты на всех.
[Ссылка 1] Стандарт C99 6.4.5 / 5 «Строковые литералы - семантика»:
На этапе трансляции 7 к каждой многобайтовой символьной последовательности, полученной в результате строкового литерала или литералов, добавляется байт или код нулевого значения. Последовательность многобайтовых символов затем используется для инициализации массива статической продолжительности хранения и длины, достаточной для хранения последовательности . Для литералов символьной строки элементы массива имеют тип char и инициализируются отдельными байтами многобайтовой последовательности символов; для широких строковых литералов элементы массива имеют тип wchar_t и инициализируются последовательностью широких символов ...
Не указано, являются ли эти массивы различными, если их элементы имеют соответствующие значения. Если программа пытается изменить такой массив, поведение не определено .
int rc
. Его время жизни заканчивается при каждой изreturn
-х. Указатели, которые вы возвращаете, относятся к строковым литералам. Строковые литералы имеют статическую продолжительность хранения: их время жизни не меньше времени жизни программы.