内存篇之指向栈的指针


原文地址: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\n", 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\n", 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\n", str);

    }

    把原先的数组修改成指针,即 char *str="hello",这样也可行,因为"hello"串位于常量数据区,在子函数结束后依然有效,通过返回的p指针仍然可以读取这块内存。

      栈本身主要是由编译器静态维护和管理,所以程序中一般情况下应该避免使用指向栈的指针

你可能感兴趣的:(C/C++,内存,栈,指针)