c/c++内存中的两个重要部分

栈和静态区是内存中的两个重要部分。C/C++会把内存划分成两大块:静态存储区和动态存储区。静态存储区在编译链接时就确定下来,只有程序退出时才会回收。动态存储区则是在运行过程中根据需要动态分配,需要手动释放。常量字符串、全局变量、局部静态变量等都属于静态区。 下面看一段代码: ```c char GetStr() { char p[] = "Hello"; return p; } int main() { char str = NULL; str = GetStr(); printf("%s", str); return 0; } ``` 这个代码看起来好像没什么问题,但实际上隐藏着危险。函数GetStr()返回了一个局部变量p的地址,而这个变量位于栈上。当GetStr()函数执行完毕后,栈帧被销毁,指针p指向的内存就无效了。因此,当我们在main()函数中使用这个指针时,程序很可能会崩溃。 不过,如果我们把代码稍微改一下: ```c char GetStr() { static char p[] = "Hello"; return p; } ``` 这次就能顺利输出"Hello"。因为这里使用了static修饰符,数组p就被放置在静态存储区中,它的生命周期一直延续到程序结束。 在编写函数时要注意区分不同类型的变量。如果需要返回一个字符串地址,一定要确保该地址是指向有效内存的。可以考虑使用全局变量、堆内存或者static局部变量来解决问题。全局变量方便快捷但不支持多线程环境;堆内存需要手动管理否则会导致内存泄漏;static局部变量可以让编译器帮你管理内存但同样不支持多线程环境。 总结一下:如果返回局部变量的地址,程序很有可能崩溃(99%);如果返回静态或常量字符串的地址,则可以安全使用。 下次再写函数时,如果想要优雅地传递字符串给调用者,请先问自己:它应该存放在栈上还是静态区里?