2016-03-22 3 views
-3

СитуацияDe-Реферирование недействительным ошибка указателя, когда Infact уже ввергнуть

Рассмотрим следующий исходный код, который направлен на печать двух элементов а, т.е. выход должен быть «аа»:

#include <stdio.h> 

int main() 
{ 
char a = 'a'; 
void* a_pnt = &a; 
void* b_pnt = (char*)a_pnt; 

printf("%c", *(char*)a_pnt); 
printf("%c", *b_pnt);// why is the compiler saying I am dereferencing a void pointer? It was already cast 
return 0; 
} 

Усложнение

Печать первого «а» работает, но компилятор дает ошибку времени компиляции в строке 10 (вторая печать «а»):

Неправильное использование пустого выражения

и предупреждение на той же линии, говоря:

Разыменование Пустота * указатель

Хотя b_pnt действительно был объявлен void, он был привязан к указателю на символ в его определении в строке 7. Мое единственное предположение, почему его жалобы связаны с тем, что я могу только c ast при обращении в одно и то же время. Моя догадка основана на том, что первая переменная работает просто отлично.

Решение

Решения объявить и определить переменный характер под названием «б» и приведение к указателю символов авансом перед печатью:

#include <stdio.h> 

int main() 
{ 
char a = 'a'; 
void* a_pnt = &a; 
void* b_pnt = a_pnt; 
char b = *((char*)b_pnt); 

printf("%c", *(char*)a_pnt); 
printf("%c", b);// why is the compiler saying I am dereferencing a pointer? 
return 0; 
} 

все еще остается вопрос: Почему начальным попытка провалилась?

Я намеренно начинаю с указателя void, чтобы проиллюстрировать проблему. Этого действительно можно было избежать полностью с правильным типом указателя.

+0

Почему 'void *', но не 'char * b_pnt = a_pnt'? – ensc

+1

'(cast) expr' не влияет на тип' expr'. Это влияет только на тип '(cast) expr'. – EOF

+0

@ensc Я намеренно начинаю с указателя void, чтобы проиллюстрировать проблему. Этого действительно можно было избежать полностью –

ответ

1

Просто потому, что вы выполнили бросок при назначении b_pnt, это не значит, что он изменен. Это тип по-прежнему void * и разыменование это ошибка.

Вы можете свободно присваивать любой тип функционального указателя void * без предупреждения. Но компилятор не отслеживает, какой именно указатель хранился там, поэтому он по-прежнему остается void *, который необходимо выполнить, прежде чем его можно будет разыменовать.

+0

Он был снят до разыменования, хотя и не в том же самом заявлении. –

+0

@DeanP Он не был брошен в любой момент. Вы присвоили значение cast на 'b_ptr', но это не изменило его тип. Он также не делает его несвязанным выражением. Кастинг типа переменной изменяет тип * значения переменной в этом контексте *, а не самой переменной. – dbush