首页
社区
课程
招聘
[讨论]有趣的笔试题,关于C函数堆栈的,我的理解还不够透彻,求高手~~
发表于: 2014-4-10 15:03 7580

[讨论]有趣的笔试题,关于C函数堆栈的,我的理解还不够透彻,求高手~~

2014-4-10 15:03
7580
#include<iostream>
using namespace std;
int main()
{
        int a=100,b=150,c=200;
        int d;
        int const *s=&b;
        const int *t=&b;
        cout<<*(++s)<<" "<<*(--t)<<endl;
        return 0;
}
下列程序的输出结果是什么?
A 150 150        B 200 100         C 100 200     D 程序有错误

很明显怎样都是选D 。。。可是谁能帮忙分析下系统栈是如何存a b c? ++s ++t 取地址后到底发生了什么?指针s是不可更改的,可是之后++s,程序跑起来竟然没报错?

我把这个程序简化,看了一下main系统栈中存储的a ,b ,c的值如下,而如果按这张图的话,++s和--t指向的就是cc的空值,这是为什么?
0x001DFE46 cc cc cc cc cc cc cc cc c8 00 00 00 cc cc cc cc cc cc cc cc 96 00 00 00 cc cc cc cc
0x001DFE64  cc cc cc cc 64 00 00 00

我在VS下调试输出的都是乱码。。。

参见这个帖子http://bbs.pediy.com/showthread.php?t=186434

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (16)
雪    币: 185
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
楼主你的C语言知识需要补一下了。

        int const * pT1 = &a1;
        const int * pT2 = &a1;
        int * const pT3 = &a1;

这三种情况理解理解吧。
2014-4-10 15:18
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
理解的!第一行、第二行表示a1不可修改,第三行表示指针pT3不可修改
2014-4-10 15:35
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
哦,我上面说错了,其实两个const表示的含义是一样的,对指针的改变不影响
2014-4-10 15:36
0
雪    币: 119
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
同求解。。。
2014-4-10 15:42
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢,这题我想清楚了
2014-4-10 17:23
0
雪    币: 19
活跃值: (155)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
我怎么跑出来等于C? 100 200 刚在VC上跑的。。
2014-4-10 19:37
0
雪    币: 183
活跃值: (1284)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
8
这个结果与编译器的优化有很大关系啊,release下直接就不存在a和c了。 debug下a,b,c旁边都填充了cc
2014-4-10 20:11
0
雪    币: 19
活跃值: (155)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
刚刚测试了一下,楼主可以看看。
http://jesse.wpsec.org/?p=56
2014-4-10 20:21
0
雪    币: 2120
活跃值: (73)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
[QUOTE=曹小杰;1274174]刚刚测试了一下,楼主可以看看。
http://jesse.wpsec.org/?p=56[/QUOTE]

咦 你是想来阿里哪个部门? 我在阿里
2014-4-10 21:31
0
雪    币: 19
活跃值: (155)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
11
想去安全类的部门,我报的就是安全工程师,只是现在都没得到任何通知
2014-4-10 23:56
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
[QUOTE=曹小杰;1274174]刚刚测试了一下,楼主可以看看。
http://jesse.wpsec.org/?p=56[/QUOTE]

“在栈中,main函数开辟的空间是0×58 + 局部变量需要的大小”
为什么是0x58呢?能解释得再详细点吗?谢谢!
2014-4-11 09:25
0
雪    币: 19
活跃值: (155)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
13
那是初始化的时候系统自己分配的,我也是在调试的时候看到esp到第一个变量的距离是0x58。
2014-4-11 11:06
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
我在vs2005 和2012上调试输出都是 -858993460 -858993460。生成的汇编代码如下:
  int a=100,b=150,c=200;
01094EEE C7 45 F8 64 00 00 00 mov         dword ptr [ebp-8],64h  
01094EF5 C7 45 EC 96 00 00 00 mov         dword ptr [ebp-14h],96h  
01094EFC C7 45 E0 C8 00 00 00 mov         dword ptr [ebp-20h],0C8h  
  int d;
  int const *s=&b;
01094F03 8D 45 EC             lea         eax,[ebp-14h]  
01094F06 89 45 C8             mov         dword ptr [ebp-38h],eax  
  const int *t=&b;
01094F09 8D 45 EC             lea         eax,[ebp-14h]  
01094F0C 89 45 BC             mov         dword ptr [ebp-44h],eax  

可以看到,每个变量之间都相隔8个字节,全都是cc cc cc cc   cc cc cc cc 所以++s , --t后,指向的值为cc cc cc cc, 解释为有符号int,则输出为-858993460
2014-4-11 11:46
0
雪    币: 70
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
[QUOTE=cqqcdh;1274315]我在vs2005 和2012上调试输出都是 -858993460 -858993460。生成的汇编代码如下:
  int a=100,b=150,c=200;
01094EEE C7 45 F8 64 00 00 00 mov         dword ptr [ebp-8],64h  
0109...[/QUOTE]

很显然和编译器有关,VC++6.0,输出的是 :100,200
2014-4-11 12:10
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
恩,看编译器生成的代码, 依赖于编译器在栈上是怎么对变量布局的,  估计VC6的变量地址是直接挨在一起的,所以是100,200。
2014-4-11 12:19
0
雪    币: 9
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
恩,看编译器生成的代码, 依赖于编译器在栈上是怎么对变量布局的,  估计VC6的变量地址是直接挨在一起的,所以是100,200。
2014-4-11 12:24
0
游客
登录 | 注册 方可回帖
返回
//