zoukankan      html  css  js  c++  java
  • 一道google笔试题的简单分析

      这是2012年9月24日google的笔试题目(大意):

    #include <stdio.h>
    
    
    char* fun()
    {
        char X[100];
        sprintf(X, "Hello World!");
        return X+6;
    }
    
    int main()
    {
        printf("%s", fun());
        return 0;
    }

      对于上面的程序,会不会崩溃,如果不会崩溃,那么会输出什么? 【可选项大致有1)一定会崩溃 2)可能会崩溃,输出World 3)、、、忘了】

      对这道题目我进行分析下:

      1.首先,fun返回的是一个指针,即fun函数局部变量X的地址+6,而main函数中是要以字符串形式输出X+6开始地址上的数据;

      2.我们知道X[100]是分配在栈上的空间,在函数返回时,局部数据将会被”清除“;由于栈上空间的分配是线性分配,具体来说就是从高地址向低地址分配,ESP指向栈顶,即栈空间的分配和释放是通过减小或增大ESP的值来实现。那么在释放局部数据X[100]时,实际上只是简单对ESP实施了加100的偏移实现,而对数据并未进行任何操作,即原来数据仍然在栈上,只不过不在EBP和ESP之内。这也就是为什么前面的“清除”要加引号的缘故。因此即使函数返回,但访问X+6仍然可以指向字符串“World”,是不是因此最后输出的就是World呢?实际测试,不是!!

      3. 在函数返回后,访问X+6,实际上该地址是栈上的地址,但并非介于ebp和esp内,并且处于esp的低地址方向,即该地址可以再次被分配利用。

      4. printf("%s",X+6)时,X+6仍然指向World。那么输出为什么不是World呢?通过跟踪printf发现,由于printf函数需要大量的栈空间,所以X+6指向的地方被再次利用,原来的数据被覆盖了!!所以输出不是World(注:Win下测试,输出空;Mac下测试输出sionq)。那么输出什么呢?不确定,取决于printf函数的实现。在考场上可能没时间调试,故不确定输出什么。

      5.      关于崩溃,姑且认为是不可能的。   因为x是个有效地址,所以X+6必然也是个有效的地址,故不存访问地址出错,故不崩溃。

    总结一下:首先,输出是不确定的,取决于printf函数内部对栈空间的使用,再者程序一定不会崩溃。

                                                                                                                                                                                                    

  • 相关阅读:
    软件工程课程建议
    结对编程2
    结对编程---《四则运算》
    AVAudioPlayer播放音乐
    《问吧》需求分析
    有关结对编程的感想
    UItabBarController
    ViewController 视图控制器的常用方法
    <问吧>调查问卷心得体会
    UINavigationController导航控制器
  • 原文地址:https://www.cnblogs.com/rainduck/p/2700937.html
Copyright © 2011-2022 走看看