Почему я могу изменить значение переменной const char *? - PullRequest
21 голосов
/ 13 января 2009

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

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

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

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

Ответы [ 6 ]

35 голосов
/ 13 января 2009

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

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

char * const str = "something";

или

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

Const-указатели на неконстантные данные обычно менее полезны, чем указатель-на-const.

13 голосов
/ 13 января 2009

Далее, как мы можем защитить 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 acter
  • str2 является указателем на char acter const ant
  • str3 - const ant указатель на char acter const ant

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

2 голосов
/ 14 января 2009

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

1 голос
/ 13 января 2009

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

1 голос
/ 13 января 2009

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

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

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

1 голос
/ 13 января 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...