char *str="string1";
*str = "string2"; --> Gives a segmentation fault
puts(ptr);
Ваше назначение *str = "string2";
является нарушением ограничения .
Стандарт C (возможно, к сожалению) не требует, чтобы компиляторы C отклоняли неправильные программы.Это требует диагностических сообщений для определенных видов ошибок, но в некоторых случаях не все компиляторы даже делают это.Вы должны выяснить, какие опции использовать, чтобы получить его для диагностики большего количества ошибок.
Если ваш компилятор действительно выдал вам предупреждающее сообщение, не игнорируйте его .Предупреждения от компилятора C могут касаться незначительных стилистических проблем, или они могут касаться вещей, которые вы ожидаете рассматривать как фатальные ошибки.Вам нужно научиться различать разницу.
*str
имеет тип char
."string2"
является строковым литералом, имеет тип char[8]
и массив char
.Но в большинстве случаев (это еще одна странная вещь в C), выражение типа массива обрабатывается как выражение типа указателя.Так что "string2"
обрабатывается как выражение, дающее результат типа char*
, указатель на 's'
в "string2"
.
C не поддерживает присваивание для массивов.
Не имеет смысла присваивать значение указателя объекту char
(маленькое целое число) - но в старых версиях C десятилетия назад не было четкого различия между целыми числами и указателями.В идеале современный компилятор C должен просто отклонить присваивание из-за конфликта типов, но ваш генерирует код, который принимает адрес типа char*
, обрабатывает его как целое число, усекает это целое значение для хранения в одном байте и пытается сохранить его в 0-м элементе массива.(Вы все еще можете сделать это в современном C с приведением, явным преобразованием, но вы все равно не хотите этого делать.)
Так почему же ошибка сегментации?Строковые литералы доступны только для чтения.(Ну, вроде как, длинная история; они не гарантированы только для чтения, но часто так и есть.) Таким образом, кусок памяти, содержащий массив "string1"
, защищен операционной системой от изменения.Ошибка сегментации, убивающая вашу программу, заключается в том, как ОС реагирует, когда вы пытаетесь обойти эту защиту.
Кстати, последняя строка должна быть puts(str);
, а не puts(ptr);
.При публикации вопроса здесь всегда лучше скопировать и вставить скомпилированный код точный .Если есть ошибки, нам нужно знать, являются ли они ошибками в вашем реальном коде или просто опечатками.