突然想测一测电脑数据在内存中存放模式是小端的还是大端的,而且感觉自己对指针的掌握已经独步天下......
于是乎,挥笔写下如下程序:
int main()
{
char a = 0;
char b = 0;
char c = 1;
char d = 0;
int * p = (int *)&d;
printf("%d\n", *p);
/*
printf("%d\n", &a);
printf("%d\n", &b);
printf("%d\n", &c);
printf("%d\n", &d);
*/
return 0;
}咦?输出竟然不是256(小端)或者65536(大端)
在加入了注释的代码后,又神奇地正常显示256了!
什么鬼?难道printf还能改变变量的值不成?
a,b,c,d这四个变量不是在栈中连续排列的吗?地址不是应该连续的吗?为什么转为整型时出bug了?
反汇编看了一遍:
注释时是这样的:
0x0040134E mov BYTE PTR [esp+0x1f],0x0 //char a;
0x00401353 mov BYTE PTR [esp+0x1e],0x0 //char b;
0x00401358 mov BYTE PTR [esp+0x1d],0x1 //char c;
0x0040135D mov BYTE PTR [esp+0x17],0x0 //char d;
0x00401362 lea eax,[esp+0x17]
0x00401366 mov DWORD PTR [esp+0x18],eax //int * p = (int *)&d;取消注释时是这样的:
0x0040134E mov BYTE PTR [esp+0x1b],0x0
0x00401353 mov BYTE PTR [esp+0x1a],0x0
0x00401358 mov BYTE PTR [esp+0x19],0x1
0x0040135D mov BYTE PTR [esp+0x18],0x0
0x00401362 lea eax,[esp+0x18]
0x00401366 mov DWORD PTR [esp+0x1c],eaxexcuse me ?
下面那个显示正常,上面那个直接错了,原因在于按顺序定义的变量在栈中竟然是不一定按顺序排的!
和编译器的设计和选项有关,标准并没有规定一定要按顺序!网传debug模式下,变量两次都会插入特殊变量
结论:虽然强制转型+指针有无穷的威力,但你永远不知编译器还干了什么......
本文通过一个实例探讨了C++中连续定义的局部变量在栈上的地址可能不连续的情况,指出这与编译器设计和选项有关,标准并未规定顺序,并提醒程序员不应过分依赖这种假设。
409

被折叠的 条评论
为什么被折叠?



