Intereting Posts
игнорируя файл lib.a, файл был создан для архива, который не связан с архитектурой (x86_64) Заметив странное поведение со строками в c почему мы не можем напечатать значение в двоичной форме, как десятичная, восьмеричная, шестнадцатеричная форма? Как работать с FileChooser в GTK со статической компиляцией Как проверить, установлено ли «set» в c Какая самая большая точка кода для 16-битного типа wchar_t? Как сравнить концы строк в C? Векторная реализация дополнительной функции ошибки erfcf () Файл заголовка C с растровыми шрифтами No Clang предупреждение для неинициализированного поля в структуре используя новый путь с execve для запуска команды ls как исправить strcpy, чтобы он обнаруживал перекрывающиеся строки Определенный файл токена C для flex? компиляция моего собственного ядра (не из источника linux-kernel) беззнаковое длинное шестнадцатеричное представление

Изменить строковый литерал в C-указателе?

Возможный дубликат:
Почему я получаю ошибку сегментации при записи в строку?

У меня есть следующая программа:

char *s = "abcdf"; char s1[50] = "abcdf"; s1[0] = 'Q'; // Line 1 s[0] = 'P'; // Line 2 

Почему Line 1 работала правильно, а Line 2 вызвала сбой программы?

Строка 2 указывает на раздел данных вашего исполняемого файла, который доступен только для чтения, тогда как в строке 1 программа инициализирует массив s1 с заданной строкой. Это сохраняется в стеке, который вы можете изменить.

 char *s = "abcdf"; char s1[50] = "abcdf"; s1[0] = 'Q'; // Line 1 s[0] = 'P'; // Line 2 

Здесь s – гарантированный изменяемый указатель, который может быть глобальной переменной или локальной переменной стека в зависимости от того, помещаете ли вы это определение в область программы или внутри функции. Когда-нибудь, прежде чем вы начнете использовать его, компилятор должен учесть, что адрес текста «abcdf» должен быть загружен в s . Как правило, в современных операционных системах сама «abcdf» будет находиться в области памяти только для чтения, где «загрузчик», который считывает файл программы в память при подготовке к выполнению, сообщает самому процессору разрешить операции чтения, но не записи. Таким образом, s – который является изменяемым – указывает на «abcdf», которого нет.

s1 – гарантированный модифицируемый массив из 50 символов. Когда-нибудь, прежде чем вы начнете использовать его, компилятор должен будет скопировать текст «abcdf» в этот модифицируемый буфер. Затем вы можете безопасно модифицировать этот буфер так же, как и с s1[0] = 'Q' .

s[0] = 'P' использует указатель s для поиска исходного немодифицированного / постоянного текста «abcdf» в постоянной памяти, а затем пытается его изменить. Как уже упоминалось выше, CPU, как правило, настроен на реакцию, генерируя исключение / ловушку / сигнал / прерывание CPU (терминология отличается от производителя). Ваша программа завершится неудачей.