Подтвердить что ты не робот

Простая инициализация указателя

Некоторое время я использовал указатели, и я просто хочу быстро проверить, как я могу инициализировать целочисленный указатель?

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!

4b9b3361

Ответ 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:

  • Когда вы это сделаете:

    int tmp = 0;
    int *tmpPtr = &tmp;
    Mem::Copy((void*)tmpPtr, basepointer(), sizeof(int));
    

tmpPtr указывает на адрес переменной tmp и находится в stack. И обратите внимание, что "безопасная область", на которую указывает tmpPtr, представляет собой размер tmp (который равен 4 на некоторых машинах и 2 в других). Если вам нужно скопировать больше, чем sizeof (int) байт в tmpPtr, вы рискуете сломать стек.

  • Когда вы это сделаете:

    int *tmpPtr = 0;
    Mem::Copy((void*)tmpPtr, basepointer(), sizeof(int));
    

Значение 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 указывает "нигде"; то есть недействительной ячейкой памяти. Вы должны назначить правильную ячейку памяти указателю, как и в предыдущем фрагменте.