Почему я могу изменить значение переменной const char *?

Почему работает следующий код в C?

const char* str = NULL;
str = "test";
str = "test2";

Так как str является указателем на постоянный символ, почему нам разрешено назначать ему разные строковые литералы? Кроме того, как мы можем защитить str от модификации? Похоже, что это может быть проблемой, если, например, позже мы назначили str более длинной строке, которая закончила писать другую часть памяти.

Я должен добавить, что в своем тесте я распечатал адрес памяти str до и после каждого из моих назначений, и он никогда не менялся. Итак, хотя str является указателем на const char, память фактически изменяется. Я задавался вопросом, возможно ли, что это проблема с C?

Ответ 1

Вы меняете указатель, который не является константой (предмет, указывающий на const).

Если вы хотите, чтобы указатель был const, объявление будет выглядеть так:

char * const str = "something";

или

char const * const str = "something";  // a const pointer to const char
const char * const str = "something";  //    same thing

Указатели констант к неконстантным данным обычно являются менее полезной конструкцией, чем указатель на константу.

Ответ 2

Кроме того, как мы можем защитить str от изменения?

char * const str1; // str1 cannot be modified, but the character pointed to can
const char * str2; // str1 can be modified, but the character pointed to cannot
const char * const str3 // neither str3 nor the character pointed to can be modified.

Самый простой способ прочитать это - начать с имени переменной и прочитать влево:

  • str1 - это const ant указатель для char.
  • str2 - указатель для оператора char const ant
  • str3 - это const ant указатель для char. const ant

ПРИМЕЧАНИЕ. Чтение справа налево не работает в общем случае, но для простых объявлений это простой способ сделать это. Я нашел java апплет на основе кода с языка программирования C, который может расшифровать объявления с полным объяснением, как это сделать.

Ответ 3

В соответствующей заметке обязательно взгляните на " указатель const или указатель на const". Это помогает с тем, что некоторые люди называют константой. Я держу его в своих закладках, чтобы время от времени я мог ссылаться на него.

Ответ 4

Память для строковых литералов выделяется в стеке, и все ваши назначения изменяют указатель str, чтобы указывать на эти адреса памяти. Постоянный характер, на который он указывал первоначально, не изменился вообще.

Ответ 5

То, что вы ищете, может быть синтаксисом...

const char* const str = NULL;
str = "test";
str = "test2";

Обратите внимание на "const" после char *, который дает ошибку компилятора при попытке компиляции/сборки.

Ответ 6

Прошло некоторое время, но я считаю, что приведенный выше код является указателем на 'const char. Если я правильно вас понимаю, вам нужен постоянный указатель на "char".

Попробуйте это

char const * str = "test";

Ответ 7

Кроме того, объявление переменной как const означает, что переменная доступна только для чтения; это не означает, что значение является постоянным!