Это сложный предмет, если вы не знаете, что происходит «под капотом». C ++, скорее, «голый металлический» язык программирования и редко делает что-либо безопасным.
Глядя на код, который вы предоставляете, и отмеченные достопримечательности:
Первая строка имеет: int x, *p, *q;
, который объявляет и определяет некоторые переменные в стеке, но не инициализирует их. Также C ++ не помнит во время выполнения, что это произошло. Вы можете получить некоторые предупреждения во время компиляции, но в противном случае вам придется отслеживать вещи в своей голове.
Итак, в строке 1.
мы не знаем, равно ли q &x
или нет. Если q не инициализирован, то он может указывать куда угодно, но C ++ не знает об этом и попытается записать значение 3 в какой-то фрагмент памяти. Ответ на этот вопрос заключается в том, что C ++ не отслеживает значения указателей.
В строке 3.
снова C ++ пытается записать целочисленное значение в некоторый фрагмент памяти, но на этот раз его в куче и в многопоточной программе, возможно, было перераспределено к моменту выполнения этой строки. Так что, к сожалению, q
и *q
сохраняют значение, но вряд ли оно будет означать то, что мы хотим.
В строке 4.
это та же проблема, что и 3.
, но только если (x==0)
, и, как вы говорите, да, память могла быть перераспределена, даже если мы ее удалили.
Объявление указателя типа int выделяет память только для указателя в стеке.
Разыменование указателя означает доступ к памяти для чтения или записи, на которую указывает указатель.
Что касается вашего второго куска кода:
int *x; <-- Declares a pointer and allocates it on the stack
x = new int; <-- Allocate a new int on the heap and remember its address in x
*x = 5; <-- Overwrite the new int on the heap.
x = new int; <-- Another allocation and remember its address in x
Now we have forgotten where the first allocation was
Разыменование означает чтение или запись в память, на которую указывает указатель. Если вы просто читаете или пишете в сам указатель, то это всегда безопасно. Вот почему вы можете обойти указатель null
и попадать в неприятности только тогда, когда он разыменовывается в первый раз.