Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 双指针指向int变量以覆盖内存_C_Pointers_Memory_Int_Double - Fatal编程技术网

C 双指针指向int变量以覆盖内存

C 双指针指向int变量以覆盖内存,c,pointers,memory,int,double,C,Pointers,Memory,Int,Double,我直接输入代码 #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); r

我直接输入代码

#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;
}

为什么变量
a
0x 0000
b
0x4014 0000

代码的行为未定义

一旦将
p
设置为非
double
类型的某个对象的地址,就不能取消引用


要查看编译器对此输入所做的操作,请检查生成的程序集。

代码的行为未定义

Clang编译器生成警告消息:

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);
            ~~     ^~~~~~~

这是未定义的行为。另外,
double
5对应于64位整数
0x40140000000000000
,因此您可能可以知道发生了什么。提示:
double
可以大于
int
。您会得到意外的结果,因为您对编译器撒了谎,它找到了报复您的方法。您告诉编译器,
&(test.a)
是一个
双精度
的地址,但它是一个整数的地址。您可以随意调整优化设置,让编译器编译结果与代码不匹配的代码。@Bathsheba刚刚在这里写到输出与代码不匹配,所以,你为什么要推翻我的否决票?!该代码是一个严格的别名冲突,因此是完全未定义的行为。对未定义行为的影响进行推理是毫无意义的。在我的计算机中,
int
占用4个字节,
double
占用8个字节,我使用双指针指向int和赋值,它应该覆盖变量b的值,所以我认为b应该是5,a应为0。
1075052544
是一个固定值,不会随每次运行或更改优化而更改。您可以想什么就想什么。这显然不是正在发生的事情。事实仍然是,行为未定义。双精度5对应于64位整数
0x401400000000
。因此我得到
b
0x4014 0000
,变量b的值是4个字节的另一半。@UKeeySDis:您可以通过将64位整数设置为给定值,将双精度设置为另一个值,并调用
memcmp
。所有完美定义的行为。这确实是一个好主意,我验证它。但是为什么双5对应于64位整数
0x401400000000
?它是如何存储的?非常感谢。
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);
            ~~     ^~~~~~~