2014-09-09 8 views
0

У меня есть код, который выглядит примерно так:Как разыменовывать двойной ничтожной указатель на Int указателя

int num = 5; 
int *ptr = # 
void **xptr = &ptr; 
printf ("values:%d\n",**(int *)xptr); 

Почему я не могу разыменования недействительного двойной указатель, который указывает на указатель ИНТ ? Ниже приводятся примеры из двух примеров: .

Сниппет: 1

int *ptr = # 
int **xptr = &ptr; 
printf ("values:%d\n",**xptr); 

Сниппет 2:

void *ptr = # 
printf ("values:%d\n",*(int *)ptr); 

ответ

2

void ** не является общим указателем в отличие от void *. Любое значение void **, с которым вы играете, должно быть где-то в значении void *. Компилятор должен поднять предупреждение для void **xptr = &ptr;:

[Warning] initialization from incompatible pointer type [enabled by default] 

Вы можете сделать это следующим образом

int num = 5; 
void *ptr = # 
void **xptr = &ptr; 
printf ("values:%d\n", *((int *)*xptr)); 

Для более детального объяснения, прочитайте comp.lang.c FAQ list · Question 4.9.

+0

, да, это породило предупреждение для void ** xptr = & ptr. Спасибо за указание, что значение void ** должно быть адресом void *, а не адресом int или char. 'voidPointer.c: 6: 19: предупреждение: инициализация из несовместимого типа указателя [включена по умолчанию] void ** xptr = &ptr;' – hmmm

+0

Спасибо за этот FAQ, Q4.9 действительно отвечает на мой вопрос. – hmmm

2

Решение состоит в том, чтобы использовать оба asterics с обеих сторон.

printf ("values:%d\n",**(int **)xptr); 

Почему? Потому что иначе вы даете компилятору ложную информацию о том, что вы действительно делаете. Стили C-стиля могут быть вынуждены скомпилировать все, но вы должны осознавать себя: если вы вынуждаете компилятор что-то делать, тогда не обвиняйте его в том, что он создает вероятный аварийный код.

Мне интересно, не создавал ли компилятор предупреждение об этом. Разве это и вы проигнорировали предупреждение?

Имейте в виду, что ваша инициализация, вероятно, неверна для xptr. См. Сообщение от haccks here.

+0

My downvote. 'void ** xptr = &ptr;' не имеет смысла в фрагменте кода OP. Предлагаем 'printf (" значения:% d \ n ", ** (int **) xptr);' неверно. – haccks

+0

Это решение не так, если я прав. Просто его инициализация для получения '' xptr'' может быть неправильной. –

+0

Тогда вы должны исправить это, иначе оно будет считаться неправильным. – haccks

Смежные вопросы