问题:
你有没有想过,当你声明一个简单的字符串常量的时候,发生了什么?这些字符串放到了哪里?讲道理,这里的变量 str 是该字符串的地址,那么hello world存到了哪里?char *str="hello world";
解决:
是这样,这个 hello world 作为字符串常量被存到了静态存储区中。要更好的理解我们需要一些概念:
三种存储空间:堆、栈、静态存储区
1、局部变量存储在栈中
2、全局变量、静态变量(全局和局部静态变量)存储在静态存储区
3、new申请的内存是在堆中
4、字符串常量也是存储在静态存储区
补充说明:
1、栈中的变量内存会随着定义所在区间的结束自动释放;而对于堆,需要手动free,否则它就一直存在,直到程序结束;
2、对于静态存储区,其中的变量常量在程序运行期间会一直存在,不会释放,且变量常量在其中只有一份拷贝,不会出现相同的变量和常量的不同拷贝。
举一个例子:
int i=5;// 5存在栈中
char *p="apple";//apple存在静态存储区,而p存在栈,程序结束退出
int *j=malloc(sizeof(int)*5);//j指向的那片内存为堆
接下来我们用一个实验说明字符串常量的储存情况:
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
char *test1(char *s)
{
cout<<"in test1:\nthe address in char *"<<static_cast<void*>(s)<<endl;
char p[]="hello world";
cout<<"address in p[]:"<<static_cast<void*>(p)<<endl;
return p;
}
int main()
{
char *str="hello world";
cout<<"in main:"<<static_cast<void*>(str)<<endl;
cout<<test1("hello world")<<endl;
return 0;
}
输出:
可以看到 “hello world”的地址始终没有变化(原因是它存在静态存储区),但是当声明 char p[]时,输出的地址发生了变化,这是因为程序在这时拷贝了一份字符串,将它存入了栈中,且它的作用域为函数作用域,即出了函数块(这个例子中是test1),copy的字符串被删除了,所以这时候输出这个地址指向的区域得到的结果是无意义的。
总结
字符串常量 (双引号中的)被放在静态内存区。因为字符串常量很少需要修改,放在静态内存区会提高效率。