2014-01-24 3 views
2
#include <stdio.h> 
#include <string.h> 

main() 
{ 
    int an_int; 
void *void_pointer = &an_int; 
double *double_ptr = void_pointer; 
*double_ptr = 10; 

printf("%d", sizeof(*double_ptr)); 

} 

Вывод этой программы 8.
Как это происходит ??
Я имею в виду, что double_ptr указывал на 4-байтовую память, но все равно вывод равен 8.
* Откуда берутся другие 4 байта ??? Эта программа должна потерпеть крах, поскольку другие 4 байта не выделяются на нее. *
Пожалуйста, объясните?INT указатель на пустой указатель, а затем в двойной указатель

+0

Sidenote: вы должны использовать '% zu' при печати значений с типом' size_t'. – user694733

ответ

6

С статически типизированных, выражение sizeof *double_ptr исключительно вычисляется в соответствии с этими правилами статических типов, а именно double_ptr указывает на double, который имеет размер 8.

Эта программа имеет неопределенное поведение, потому что вы пишете область памяти, которую вы не «владеете». Все ставки отключены, это может привести к сбою или нет. Когда вы делаете такие неприятные преобразования, вы отвечаете за это, а не за компилятор.

Edit, для nitpicks:

  • функции без типа возвращаемого значения не должны допускаться на соответствующем компилятором. увеличьте уровень предупреждения.
  • при размещении кода здесь, пожалуйста, отступы это правильно
  • результат оператора sizeof не int но size_t без знака типа. Печать с "%d" также имеет неопределенное поведение. Используйте "%zu".
2

Я имею в виду double_ptr указывал на 4 байта памяти, но по-прежнему выход 8.

Это потому, что sizeof оценивается на основе типа или типа выражения. Более того, в этом случае он может быть полностью оценен во время компиляции независимо от значения указателя.

* Откуда взяты другие 4 байта ???

Они относятся к области памяти, смежной с местом расположения int. Эта область не выделена объекту, который вы намеревались написать, поэтому это неопределенное поведение. Хорошие шансы - это то, что вы пишете сам указатель, что может произойти, если компилятор помещает void_pointer в память сразу после an_int.

Эта программа должна потерпеть крах, поскольку другие 4 байта не выделены для нее.

К сожалению, не все неопределенные поведения приводят к сбоям. Это обычный случай в C, когда недействительная программа не сбой. Например, все эксплоиты переполнения буфера полагаются на способность программы не сбой после проявления неопределенного поведения.

0

sizeof is compile time operator. поэтому он проверяет тип данных, которые может указывать указатель (что равно 8 байтам), поэтому выход равен 8.

int main() 
{ 
    int an_int; 
void *void_pointer = &an_int; 
double *double_ptr = void_pointer; 
*double_ptr = 10; 

printf("%d %d",*double_ptr,sizeof(*double_ptr)); 

} 

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

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