2014-01-24 180 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指針變爲void指針,然後變成雙指針

+0

旁註:打印「size_t」類型的值時應使用'%zu'。 – user694733

回答

6

C是靜態類型,表達式sizeof *double_ptr是根據這些靜態類型規則單獨計算的,即double_ptr指向double,其大小爲8

該程序有未定義的行爲,因爲您正在寫入一個您不屬於「擁有」的內存範圍。所有投注都關閉,它可能會崩潰或不崩潰。當你做這樣的惡意轉換時,你是負責的,而不是編譯器。

編輯,爲挑剔:無返回值類型

  • 功能不應該由一個符合標準的編譯是不能容忍的。提高警戒級別。
  • 張貼在這裏的代碼時,請縮進它sizeof運營商的正常
  • 結果不intsize_t無符號類型。打印與"%d"也有未定義的行爲。使用"%zu"
2

我的意思是double_ptr指着4個字節存儲器,但仍然輸出是8

這是因爲sizeof是基於類型或表達式的類型進行評價。而且,在這種情況下,無論指針的值如何,它都可以在編譯時進行全面評估。

*其他4字節來自哪裏???

它們屬於與int的位置相鄰的存儲器區域。此區域未分配給您打算編寫的對象,因此它是未定義的行爲。很有可能您正在寫入指針本身,如果編譯器在an_int之後立即將void_pointer置於內存中,可能會發生這種情況。

該程序應該崩潰,因爲其他4個字節未分配給它。

不幸的是,並非所有未定義的行爲都會導致崩潰。當一個無效的程序不會崩潰時,這是C中的一個常見情況。例如,所有緩衝區溢出攻擊都依賴於程序在展示未定義行爲後不會崩潰的能力。

0

sizeof是編譯時運算符。所以它檢查指針可能指向的數據類型(這是雙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)); 

} 

我編輯了一下。它嘗試使用指針訪問內存時崩潰。