Такие вещи, как 1
, 'a'
и "heyapple!"
называются литералами , и они сохраняются в скомпилированном коде и в памяти, когда они должны использоваться. Если они остаются или не сохраняются в памяти на время действия программы, зависит от того, где они объявлены в программе, их размера и характеристик компилятора, но обычно можно предположить, что да, они хранятся где-то в память, и что они не уходят .
Обратите внимание, что, в зависимости от компилятора и ОС, может быть возможно изменить значение литералов, непреднамеренно или преднамеренно. Многие системы хранят литералы в областях только для чтения (разделы CONST) памяти, чтобы избежать неприятных и трудных для отладки аварий.
Для литералов, которые вписываются в слово памяти, например int
s и char
s, не имеет значения, как они хранятся: каждый повторяет литерал по всему коду и позволяет компилятору решить, как сделать его доступным. Для больших литералов, таких как строки и структуры, было бы плохой практикой повторять, поэтому ссылка должна быть сохранена.
Обратите внимание, что если вы используете макросы (#define HELLO "Hello!"
), то компилятор сам решает, сколько копий литерала хранить, потому что расширение макросов - это точно, замена макросов на их расширение, которое происходит перед компилятором. снимает исходный код Если вы хотите убедиться, что существует только одна копия, вы должны написать что-то вроде:
#define HELLO "Hello!"
char* hello = HELLO;
Что эквивалентно:
char* hello = "Hello!";
Также обратите внимание, что объявление типа:
const char* hello = "Hello!";
Сохраняет hello
неизменным, но не обязательно память, на которую он указывает, из-за:
char h = (char ) привет;
h [3] = 'n';
Я не знаю, определен ли этот случай в ссылке на C, но я бы не стал на это полагаться:
char * hello = "Привет!";
char * hello2 = "Привет!"; // это та же самая память?
Лучше думать о литералах как об уникальных и постоянных и обращаться с ними соответствующим образом в коде.
Если вы хотите изменить копию литерала, использовать массивы вместо указателей , поэтому гарантированно используется другая копия литерала (а не псевдонима) каждый раз:
char hello[] = "Hello!";
Возвращаясь к исходному вопросу, память для литерала "heyapple!"
будет доступна (будет ссылочной), пока ссылка на нее хранится в работающем коде. Хранение целого модуля (загружаемой библиотеки) в памяти из-за литерала может иметь последствия для общего использования памяти, но это еще одна проблема (вы также можете вызвать выгрузку модуля, который определяет литерал и получить всевозможные странные результаты).