2017-01-30 4 views
0
#include <stdio.h> 

    int main() { 
     char c = 'A'; 
     int *int_ptr; 
     double *double_ptr; 

     *int_ptr = *(int *)&c; 
     *double_ptr = *(double *)&c; 

     printf("Original char = %c \n", c); 
     printf("Integer pointer = %d \n", *int_ptr); 
     printf("Double pointer = %f\n", *double_ptr); 

     return 0; 
    } 

квестинга - почему я не могу назначить double_ptr с помощью этого кода, поскольку он вызывает ошибку сегментации, но работает отлично подходит для целого?Cast типа указателя в C

Как я понимаю, char имеет длину 1 байт, а int - 4 байта, поэтому double имеет длину 8 байтов.

Используя выражение *(double *)&c Я ожидаю следующее:

  1. & - Получить адрес памяти с.
  2. (double *) - притворитесь, что это указатель на двойной.
  3. *() - получить фактическое значение и присвоить его двойному var.
+0

1) Вы знаете, что вы делаете, это «неправильно». 2) Если вам интересно, почему вы получаете ошибку сегментации, почему бы вам не скомпилировать с -S (gcc) или/Fa (MSVC) и посмотреть на сборку? – paulsm4

+2

Прежде всего, у вас нет памяти за указателями, поэтому '* int_ptr' адресует память, которая не принадлежит вам, то есть UB. Вы даже не знаете, где, поскольку указатель не инициализирован. Кроме того, вы пытаетесь прочитать символ (1 байт), используя int (4 или 8 байт), который снова является UB. – 4386427

ответ

3

Ваш код имеет неопределенное поведение. Поэтому все может случиться.

UB - это то, что вы производите char, который представляет собой один байт для типов с 4 и 8 байтами, что означает, что вы (потенциально) получаете доступ к памяти за пределами границы или с неправильным выравниванием.

Независимо от того, будет ли какое-либо из них «работать» или «не работать» в какой-либо конкретной системе, это не очень важно, поскольку код является ошибочным.

1

В вашей программе, напечатанный материал из char в int* или double*, а затем разыменования бы получить некоторое количество дополнительных байтов из памяти, которая неопределенное поведение.

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