Простая инициализация указателя
Некоторое время я использовал указатели, и я просто хочу быстро проверить, как я могу инициализировать целочисленный указатель?
a) int *tmpPtr = 0;
b) int *tmpPtr = null;
c) int a = 0;
int *tmpPtr = &a;
ИЗМЕНИТЬ
Спасибо за все ваши ответы. Самое смешное, что если я активирую
указатель следующим образом, то операция mem:: copy работает нормально.
int tmp = 0;
int *tmpPtr = &tmp;
Mem::Copy((void*)tmpPtr, basepointer(), sizeof(int));
Однако, если я делаю это так:
int *tmpPtr = 0;
Mem::Copy((void*)tmpPtr, basepointer(), sizeof(int));
то я получаю сбой во время mem:: copy...
Weird!
Ответы
Ответ 1
Простые вопросы в порядке, я думаю, это хорошо установлено, что SO предназначен для всех уровней, а не только для элиты.
В C нет null
в C (если вы не определяете его сами). Инициализация нулевого указателя может быть выполнена одним из двух способов:
int *p = 0;
int *p = NULL;
Если после этого вы разыгрываете p
, вы, вероятно, получите нарушение прав доступа (я считаю, что это undefined поведение в соответствии со стандартом, так что действительно может произойти что угодно, вплоть до полного аннулирования Вселенная - он может даже продолжать работать нормально, но я бы не стал полагаться на него).
Чтобы получить указатель на реальное целое число, просто используйте:
int a = 7;
int *p = &a;
используя адрес-оператора.
Повторите свое редактирование, это совсем не странно, вам просто нужно визуализировать его. Предположим, что все переменные созданы начиная с ячейки памяти 100, а целые числа и указатели имеют длину 4 байта. Разрушение двух ситуаций до их простейшей формы:
int x = 2;
int *px = 0; int *px = &x;
+-----+ +-----+
px(100): | 0 | x(100) | 2 |
+-----+ +-----+
px(104) | 100 |
+-----+
Затем вы выполняете команду
*px = 7;
в попытке изменить переменную, на которую указывает px
.
С левой стороны вы попытаетесь записать значение 7 в ячейку памяти 0. Это плохо. очень немногие системы позволят вам сделать это без сбоев, даже меньшее позволит это без каких-либо неблагоприятных эффектов вообще (некоторые версии HP-UX действительно работали нормально).
С правой стороны должно произойти то, что должно произойти. Значение, полученное от px
, равно 100, поэтому значение 7 записывается в эту ячейку памяти, изменяя x
по назначению.
Я часто нахожу фотографии (даже примитивные ASCII-арт, поскольку я не Рубенс или Боттичелли) помогают прояснить концепции. Надеюсь, это немного облегчило вам.
Ответ 2
Ответьте на свой вопрос в EDIT:
tmpPtr указывает на адрес переменной tmp
и находится в stack. И обратите внимание, что "безопасная область", на которую указывает tmpPtr, представляет собой размер tmp
(который равен 4 на некоторых машинах и 2 в других). Если вам нужно скопировать больше, чем sizeof (int) байт в tmpPtr, вы рискуете сломать стек.
Значение tmpPtr равно 0, поэтому вы получите segment fault., который является механизмом защиты памяти, предлагаемым операционной системой. Например, вам не разрешено писать любой виртуальный адрес, который меньше 4K.
Ответ 3
Вы можете сделать это любым из этих способов, кроме как NULL не равно null. Я предпочитаю int * p = 0; над int * p = NULL;
Чтобы устранить некоторую путаницу, я чувствую, устанавливая int * p = 0 или устанавливая MyObject * p = 0; приводит к тому же... нулевой указатель, который, как правило, разбивает вашу программу, если вы попытаетесь разыменовать ее, хотя технически это поведение undefined. Пример, который у вас есть в C, отличается от других, потому что вы на самом деле устанавливаете указатель на то, чтобы указать целочисленный набор как 0.
int *pNull = 0;
int c = *pNull; // Undefined behavior. Most likely crashing your program!
int a = 0;
int *pInt = &a;
int x = *pInt; // x equals 0
a = 10;
int y = *pInt; // y equals 10
Ответ 4
Инициализируйте указатели, которые не указывают на нулевую константу указателя. Любые константные выражения со значением 0 служат константой нулевого указателя. В C NULL макрос используется по соглашению.
Ответ 5
Я просто обновлял свои знания указателя и наткнулся на это.
int *tmpPtr = 0;
Мне легче думать об этом так:
int *tmpPtr ;
tmpPtr = 0 ;
Я считаю, что вышеупомянутые 2 строки эквивалентны этой одной строке.
поэтому в основном адрес, подлежащий де-ссылке, устанавливается равным 0 или NULL
.
Ответ 6
В C нет ключевого слова null
(по крайней мере, в ANSI C99). Вы можете использовать a) или c).
В c) вы не будете инициализировать указатель нулевым значением, вы инициализируете его адресом локальной переменной.
Ответ 7
Линия
int *tmpPtr = 0;
инициализирует значение указателя равным 0, поэтому tmpPtr указывает "нигде"; то есть недействительной ячейкой памяти. Вы должны назначить правильную ячейку памяти указателю, как и в предыдущем фрагменте.