原文地址: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指针仍然可以读取这块内存。 栈本身主要是由编译器静态维护和管理,所以程序中一般情况下应该避免使用指向栈的指针