zoukankan      html  css  js  c++  java
  • 内存篇-指向栈内存的指针

    原文地址:http://blog.csdn.net/ipmux/article/details/17549157
    
    
    下面程序运行有什么样的结果?
    
        char *GetString(void)
    
        {
    
          char array[6];
    
          strcpy(array, “hello”);
    
          return array;
    
        }
    
        void main()
    
        {
    
          char *pstr = NULL;
    
          pstr = GetString();
    
          printf("%s
    ", pstr);
    
        }
    
        答对这个问题,脑子里必须有一根弦,那就是栈内存里的内容如“昙花一现”,其有效的生命周期只等于函数周期,访问栈内存的前提条件是在函数运行范围内,函数一旦退出,相应的栈内存立马消散,如同镜花水月,再访问就是野指针的“非法”操作。
    
        上例中,函数char *GetString返回了指向局部数组array[6]的指针,但array[6]位于栈中,函数的栈内存在其结束后立刻失效,函数退出后再试图通过pstr访问栈内存就成了非法操作。因此,返回指向栈内存的指针这种机制,看似在函数退出后继续访问栈内存留了一个“后门”,实际上是一个隐晦的陷阱。再比较下面例子:
    
        char *GetString(void)
    
       {
    
          char array[6]=”hello”;
    
          char *p = malloc(6);
    
          strcpy(p, array);
    
          return p;
    
        }
    
        void main()
    
        {
    
          char *str = NULL;
    
          str = GetString();
    
          printf("%s
    ", str);
    
        }
    
        这里先把hello字符串从array[]所在的栈内存拷贝到指针p指向的堆内存中,当GetString 函数结束后,array[]栈内存失效了,但指针p所指的堆内存仍有效并保存着”hello”串,函数返回指向堆的指针就没有问题了。如果把直接用指针指向字符串呢:
    
        char *GetString(void)
    
        {
    
          char *p = "hello";
    
          return p;
    
        }
    
        void main()
    
        {
    
          char *str = NULL;
    
          str = GetString();
    
          printf("%s
    ", str);
    
        }
    
        把原先的数组修改成指针,即 char *str="hello",这样也可行,因为"hello"串位于常量数据区,在子函数结束后依然有效,通过返回的p指针仍然可以读取这块内存。
    
         栈本身主要是由编译器静态维护和管理,所以程序中一般情况下应该避免使用指向栈的指针
    新战场:https://blog.csdn.net/Stephen___Qin
  • 相关阅读:
    之所以菜鸟依旧
    单点登陆
    让entityframework.extend库同时支持mysql,sqlsever
    背包算法
    JS中实现继承
    Altium Designer 生成 Mach3 G代码的程序
    test博客嵌入pbi
    testPBI报表
    html中隐藏title属性方法
    Spring mvc 中有关 Shiro 1.2.3 配置问题
  • 原文地址:https://www.cnblogs.com/Stephen-Qin/p/11681431.html
Copyright © 2011-2022 走看看