2017-10-11 81 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); 
      ~~  ^~~~~~~