Возможный дубликат:
Почему я получаю ошибку сегментации при записи в строку?
У меня есть следующая программа:
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 (терминология отличается от производителя). Ваша программа завершится неудачей.