Страницы

Поиск по вопросам

пятница, 13 декабря 2019 г.

C++: изменение символа строкового литерала

#cpp #cpp_faq


#include 

int main()
{
    char* str = "qwerty";
    str[0] = '1';
    std::cout << str << std::endl;
    return 0;
}


Этот код выдает ошибку access violation. В чем дело? Почему нельзя изменить символ
простой не-const строки?

UPD: код сработал при такой инициализации строки: char str[]. Но в чем разница?
    


Ответы

Ответ 1



Строковые константы в коде могут размещаться где-то в отдельном блоке памяти (в дата-секции исполняемого файла, например), который может быть отмечен как "только для чтения". Модифицировать их нельзя, это undefined behavior. Хотя на некоторых компиляторах в некоторых осях при определённых условиях это и может работать, но полагаться на это нельзя. Если хотите иметь модифицируемую строку, то скопируйте её или объявите как массив (не как указатель). См. Why is this string reversal C code causing a segmentation fault?

Ответ 2



(Оказалось, что при редактировании комментария нельзя отвлекаться дольше, чем на 5 минут!!! Пришлось в ответ...) Кстати, нормальный крестовый компилятор (например, g++) выдаст предупреждение deprecated conversion from string constant to ‘char*’ для char* str = "qwerty"; И вообще, при изменении на char str[] = ... Вы получаете другую программу, с другим набором переменных. В первом случае у Вас в стеке указатель (4 байта для 32-бит машины) с именем str (или "по символическому адресу", что одно и то же), который содержит адрес строковой константы "qwerty" (к вашему удивлению она оказалась в read-only области памяти), а во втором по символическому адресу str в стеке отвели 7 байт (qwerty + nil). Вот эту разницу Вы и увидели при запуске.

Ответ 3



Попробуй использовать char str[] = "qwerty"; вместо char* str = "qwerty";

Комментариев нет:

Отправить комментарий