Разыменование указателя в конкретном случае - PullRequest
2 голосов
/ 31 мая 2019

Может кто-нибудь сказать мне, почему этот кусок кода не работает? Всегда говорят, что ошибка сегментации

int main()
{
    int a = 10;
    int b = (int)&a;
    int *c = (int*)b;
    printf("%d", *c);

    return 0;
}

Когда я печатаю значение c, его адрес a, как я и ожидал, но при его задержке возникает ошибка сегментации. Предположим, что это 32-битный компилятор

Ответы [ 2 ]

4 голосов
/ 31 мая 2019

a является целым числом и получает значение 10.

b является целым числом и получает в качестве значения целое число, адрес a приведен как целое число.

c является указателем на int и получает значение b, приведенное к указателю на int.

Значение b было адресом a, но приведено какинт.

Так что c «должен» указывать на a, а с *c вы «должны» получить 10. Проблема в том, что на вашей машине размер int и размер a pointer to an int не совпадают, и в первом приведении вы урезали значение &a до размера int и потеряли несколько цифр адреса.

Теперь в b есть int, содержащий только некоторую цифру адреса a и, следовательно, совершенно другой адрес, поэтому при попытке доступа к памяти по этому адресу (с *c)вы не обращаетесь к a, но где-то еще есть память, которая в этом случае оказывается недействительной.

2 голосов
/ 31 мая 2019

Иногда это будет работать, а иногда нет, это зависит от вашей машины, может быть, размер integer меньше размера указателя на вашей машине, так что если приведенный и назначенный на целое число адрес больше размера int, он переполнится, и целое число будет содержать неправильный адрес, поэтому на выходе возникнет ошибка сегментации.


Примечание


Вы можете проверить размер шрифта с помощью функции sizeof .

size_t a,b;
a=sizeof(int);
b=sizeof(int*);
if(a>=b)
printf("Valid assignment with no errors\n);
else
printf("This may cause an error if the address is larger than integer size\n);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...