zoukankan      html  css  js  c++  java
  • 【C语言学习趣事】_函数返回后的地址_游离地址空间

      前些日子,在QQ群里面,发现一些朋友在讨论函数返回后,为什么值可以传递和地址传递的情况;我也感到很好奇,

    于是就跟了一下。

    int*  sum(int x,int y)
    {
        int a;
        a=x|y;
        
        return &a;
    }

      很显然这段代码,存在一些问题;但是在VC2008中编译一切正常,运行状态也一切正常。

    下面是我的测试代码:

    #include <stdio.h>
    
    int*  sum(int x,int y)
    {
        int a;
        a=x+y;
        
        return &a;
    }
    int getsum(int x,int y)
    {
        return x+y;
    }
    int main(void)
    {
        int *x;
        int a;
        x=sum(10,2);
    
        printf("*x=%d; x=%u\n",*x,x);
        
        a=getsum(1,2);
        x=sum(10,2);
        printf("*x=%d; x=%u\n",*x,x);
    
        *x=100;
        printf("*x=%d; x=%u\n",*x,x);
        getchar();
        return 0;
    }

    运行结果如下所示:

      这个就是运行的结果?但是为什么呢?  而且两次调用sum函数返回的地址完全一样。

    为了测试,我决定将代码再进行异常改动。

    #include <stdio.h>
    
    int*  sum(int x,int y)
    {
        int a;
        a=x+y;
        
        return &a;
    }
    int getsum(int x,int y)
    {
        int* p;
        p=sum(10,2);
    
        printf("*x=%d; x=%u\n",*p,p);
        return *p;  
    }
    int main(void)
    {
        int *x;
        int a;
    
        x=sum(10,2);
        printf("*x=%d; x=%u\n",*x,x);
        
        a=getsum(1,2);
    
        x=sum(10,2);
        printf("*x=%d; x=%u\n",*x,x);
    
        *x=100;
        printf("*x=%d; x=%u\n",*x,x); 
    
           
    
        getchar();
        return 0;
    }

      代码依然坚挺的活着,而且顺利的运行,如下所示,只是在getsum里面调用sum函数,得到的地址与main函数中得到的不一样。

      而且可以发现,无论怎么调用,在main函数中调用sum,返回的地址一直是一样的?  这是怎么回事呢?

    如果是这样的话,那么是否可以用这种方法动态分配地址呢?  是否可以我们free 一下看看。很不幸的是,失败了?

      提示:可能是heap——栈——异常中断了程序。

      为什么会这样呢?

    原因可能是:

      1、C程序在运行的过程中,其地址空间是固定的;虽然是可重定向的,但是在“他”自己的线性空间,其地址空间是固定的,

    也就是所函数调用的压栈的空间,其栈基址是固定的。

      2、由于压栈顺序是一致的,而且每次压栈时变量的offset是一定的。从左往右压栈,或者从右往左压栈都一样会得到这个结果。

    因此就出现了上面的情况。

      那么怎样说明这个过程的不正常呢? 虽然他看起来能编译、链接和运行,结果也很正常。

    #include <stdio.h>
    
    int *x;
    
    int*  sum(int x,int y)
    {
        int a;
        a=x+y;
        
        return &a;
    }
    void getsum()
    {
        x=sum(10,2);    
        printf("*x=%d; x=%u\n",*x,x); //第二个输出
    }
    int main(void)
    {
        int a;
    
        x=sum(10,2);
        printf("*x=%d; x=%u\n",*x,x);  //第一个输出
        
        getsum();
        printf("*x=%d; x=%u\n",*x,x);  //第三个输出
    
        *x=100;
        printf("*x=%d; x=%u\n",*x,x);   //第四个输出 
    getchar(); return 0; }

      可以发现,第一个输出,第二输出的 *x的值一样;  而第二个、第三个、第四个则是x的只一样。这又是为什么呢?

     我们在改一下:

     #include <stdio.h

    int *x;
    
    int*  sum(int x,int y)
    {
        int a;
        a=x+y;
        
        return &a;
    }

    void getsum() { x=sum(10,2); printf("*x=%d; x=%u\n",*x,x); //第二个输出 } int main(void) { int a; x=sum(10,2); printf("*x=%d; x=%u\n",*x,x); //第一个输出 getsum(); printf("*x=%d; x=%u\n",*x,x); //第三个输出 *x=100; printf("*x=%d; x=%u\n",*x,x); //第四个输出 x=sum(10,2); printf("*x=%d; x=%u\n",*x,x); //第五个输出 getchar(); return 0; }

    又或者这样测试一下:

      

    #include <stdio.h>
    
    int *x;
    
    int*  sum(int x,int y)
    {
        int a;
        a=x+y;
        
        return &a;
    }
    
    int*  sum1(int x,int y)
    {
        int a;
        a=x+y;
        
        return &a;
    }
    void getsum()
    {
        x=sum(10,2);    
        printf("*x=%d; x=%u\n",*x,x); //第二个输出
    }
    int main(void)
    {
        int a;
    
        x=sum(10,2);
        printf("*x=%d; x=%u\n",*x,x);  //第一个输出
        
        getsum();
        printf("*x=%d; x=%u\n",*x,x);  //第三个输出
    
        *x=100;
        printf("*x=%d; x=%u\n",*x,x);   //第四个输出 
    
    
        x=sum1(10,2);
        printf("*x=%d; x=%u\n",*x,x);  //第五个输出
    
        getchar();
        return 0;
    }

    我们再改一下:

    #include <stdio.h>
    
    int *x;
    
    int*  sum(int x,int y)
    {
        int a;
        a=x+y;
        
        return &a;
    }
    
    int*  sum1(int c,int d)
    {
        int a;
        a=c+d;
        *x=60;
        return x;
    }
    void getsum()
    {
        x=sum(10,2);    
        printf("*x=%d; x=%u\n",*x,x); //第二个输出
    }
    int main(void)
    {
        int a;
    
        x=sum(10,2);
        printf("*x=%d; x=%u\n",*x,x);  //第一个输出
        
        getsum();
        printf("*x=%d; x=%u\n",*x,x);  //第三个输出
    
        *x=100;
        printf("*x=%d; x=%u\n",*x,x);   //第四个输出 
    
    
        x=sum1(10,2);
        printf("*x=%d; x=%u\n",*x,x);  //第五个输出
    
        getchar();
        return 0;
    }

      输出结果如下所示:

      发现x的地址可以一直引用。

      如果你要做一些坏事的话,这里就是一个可以利用的地方。  可以通过这个全局的x变量,来修改传递给函数的参数值。

    这个实验就不做了。

      有兴趣的可以试一下。

  • 相关阅读:
    OCP-1Z0-053-200题-36题-615
    Android换行符变成方框的解决方法
    OCP-1Z0-053-200题-35题-614
    FusionCharts 3D帕累托图
    FusionCharts 3D帕累托图报错
    FusionCharts 2D帕累托图
    OCP-1Z0-053-200题-33题-612
    OCP-1Z0-053-V13.02-612题
    OCP-1Z0-053-200题-32题-611
    OCP-1Z0-053-V13.02-611题
  • 原文地址:https://www.cnblogs.com/volcanol/p/3070245.html
Copyright © 2011-2022 走看看