Я всегда думал, что, когда вы создали переменную указатель (р), не могли бы почтительное и назначить (* р = значение), если вы либо malloc'd пространство для него (р = таНос (х)) или установить его на адрес другой переменной (* р = &)
есть вещи в C, которые запрещены, так что C компилятор выдаст ошибку и откажется компилировать программу, и есть другие вещи, для которых стандарт C не определяет какого-либо поведения, поэтому нет ограничений на то, что может сделать реализация. Причина этого заключается в том, чтобы дать реализациям широкую широту в том, как они реализованы, и позволить им производить ver y быстрый код. Это отличается от более современных языков, которые придают большую ценность защите программистов от их собственных ошибок. Как следствие, для программиста возникает большая нагрузка для написания действительного кода.
Ваш код является примером, где поведение не определено. Компилятор не генерирует проверки, чтобы узнать, действительно ли значение p
имеет место при разыменовании и назначении его ... он может содержать нежелательные сообщения, а хранилище может находиться в произвольном месте в памяти или может указывать на недоступную память и хранилище (есть другие возможности, поскольку поведение не определено, но это те, которые будут возникать в обычных реалиях реального мира). То, что ваш код разбился в одном магазине, но не другой, - это просто случайность, артефакт тонких деталей реализации ... другой компилятор, другая версия компилятора, небольшое изменение в вашем источнике ... любой из этих вещи и другие могут изменить результаты, изменив значение, которое оказалось в p
... какое-то произвольное значение осталось в стеке, потому что p
- это переменная стека (стандарт языка C не предусматривает или не упоминает стек, а обычный реалистичные реализации выделяют auto
переменных в стеке.)
Суть в том, что ваша программа, как вы знаете, неправильно, даже если она «разрешена». Как сказал в комментариях Р. Мартиньо Фернандес, вы unlucky, что первый магазин «работал» ... в коммерческом продукте, имея что-то вроде этого «работа», было бы крайне неудачным, потому что он может потерпеть неудачу в любое время, включая худшие возможные обстоятельства. Язык C не помогает вам здесь ... вам нужно быть очень дисциплинированным.
«вы не могли бы откликнуться и назначить (...), если вы не malloc'd для этого не сделали, или установите его на адрес другой переменной (...)« Это абсолютно верно. Так что не делай этого. «Почему первый работает, когда colin не указывает на какую-либо свободную память?» Потому что тебе не повезло. «И почему 2-й никогда не работает?» Потому что тебе повезло. –
Неопределенное поведение. – SBI
Маргинальное замечание к вашему последнему предложению: вы, кажется, считаете, что C - подмножество C++. К сожалению, это не так. –