2017-10-11 79 views
-5

我直接放置代碼。雙指針指向int變量來覆蓋內存

#include <stdio.h> 
struct A 
{ 
    int a; 
    int b; 
}; 
int main() 
{ 
    struct A test; 
    double *p = (double *)&(test.a); 
    *p = 5; 

    printf("variable a: %d\n", &test.a); 
    printf("variable b: %d\n", &test.b); 
    return 0; 
} 

我運行centos7這段代碼,編譯器是gcc4.8.5。而我的電腦使用的小結局店。

正如你看到的,變量b的記憶將被覆蓋,我預計a0x0000 0005b0x0000 0000

但答案是:

variable a: 0 
variable b: 1075052544 

爲什麼變量a0x 0000 0000b0x4014 0000

+5

這是不確定的行爲。此外,'double' 5對應於64位整數'0x4014000000000000',所以你可能可以弄清楚發生了什麼。提示:'double'可以大於'int'。 – unwind

+3

因爲你對你的編譯器撒謊了,你會得到意想不到的結果,並且它找到了一種回到你身邊的方法。你告訴編譯器'&(test.a)'是'double'的地址,但它是一個整數的地址。 – dasblinkenlight

+0

您可以使用優化設置進行調試,並讓您的編譯器編譯代碼,其中結果是* else *。 –

回答

4

您的代碼的行爲是undefined

一旦您將其設置爲非double類型的地址,就無法取消引用p

要查看您的編譯器對此輸入做了什麼,請檢查生成的程序集。

+0

在我的計算機中,'int'佔用4個字節,'double'佔用8個字節,我使用雙指針指向int和賦值,它應該覆蓋變量b的值,所以我認爲b應該是5,a應該是0。而'1075052544'是一個固定值,不會隨着每次運行或更改優化而改變。 – UKeeySDis

+1

你可以認爲你想要的是什麼。這顯然不是發生的事情。事實仍然是行爲未定義。 – Bathsheba

+0

double 5對應於64位整型「0x4014000000000000」。所以我得到的'b'是'0x4014 0000',變量b的值是4個字節的另一半。 – UKeeySDis

1

您的代碼的行爲是未定義的。

鏘編譯器生成警告消息:

source_file.c:13:20: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat] 
    printf("%d\n", &test.a); 
      ~~  ^~~~~~~ 
source_file.c:14:20: warning: format specifies type 'int' but the argument has type 'int *' [-Wformat] 
    printf("%d\n", &test.b); 
      ~~  ^~~~~~~