Удалить константность из переменной

я пытаюсь удалить константность из переменной (char *), но по какой-то причине, когда я пытаюсь изменить значение, исходное значение константной переменной остается прежним.

 const char* str1 = "david";
 char* str2 = const_cast<char *> (str1);
 str2 = "tna";

теперь значение str2 меняется, но исходное значение str1 остается прежним, я искал его в Google, но не смог найти четкого ответа.

при использовании const_cast и изменении значения должен ли также измениться оригинал переменной const?


person David Faizulaev    schedule 12.03.2013    source источник


Ответы (2)


Тип str1const char*. Именно char является const, а не указателем. То есть это указатель на const char. Это означает, что вы не можете сделать это:

str1[0] = 't';

Это изменит значение одного из const chars.

Теперь, когда вы делаете str2 = "tna";, вы изменяете значение указателя. Это нормально. Вы просто меняете str2, чтобы он указывал на другой строковый литерал. Теперь str1 и str2 указывают на разные строки.

С вашим указателем str2, отличным от const, вы могли сделать str2[0] = 't';, но при этом у вас было бы неопределенное поведение. Вы не можете изменить то, что изначально было объявлено const. В частности, строковые литералы хранятся в памяти только для чтения, и попытка изменить их принесет вам ужасные несчастья.

Если вы хотите взять строковый литерал и безопасно изменить его, инициализируйте им массив:

char str1[] = "david";

Это скопирует символы из строкового литерала в массив char. Затем вы можете изменить их по своему вкусу.

person Joseph Mansfield    schedule 12.03.2013
comment
Итак, есть ли способ изменить значение переменной const char* с помощью приведения? - person David Faizulaev; 12.03.2013
comment
@DavidFaiz Вы можете просто изменить указатель без приведения. Вы не можете изменить char, если вы установили указатель так, чтобы он указывал на строковый литерал, который у вас есть. Строковые литералы постоянны. См. мое последнее редактирование о том, как скопировать строковый литерал в массив. - person Joseph Mansfield; 12.03.2013
comment
да просто увидел и понял! большое спасибо за быстрый ответ! поэтому в основном я не могу изменить литеральную строку, а просто использую переменную const char и указываю на другую. - person David Faizulaev; 12.03.2013
comment
Только литералы изначально объявлены как const, верно? - person Tahlil; 25.06.2014
comment
@DavidFaiz, если это полностью ответило на ваш вопрос, вам следует пометить его как принятый ответ, щелкнув галочку слева. - person marcusshep; 10.08.2017

str2 - это просто указатель. И ваш код просто меняет значение указателя, адрес, а не строку, на которую он указывает.

Более того, то, что вы пытаетесь сделать, приводит к неопределенному поведению и, скорее всего, к ошибкам во время выполнения. Все современные компиляторы будут хранить вашу строку "david" в постоянной памяти. Попытки модифицировать эту память приведут к ошибкам защиты памяти.

person David Heffernan    schedule 12.03.2013