在讲述内存模型的时候,我们使用下面这段代码来涵盖各种内存分配的情况
#include<iostream>
using namespace std;
const double pi=3.1415926; //常量
static int out=0; //静态全局变量
int i=1; //初始化了的全局变量
int j; //未初始化的全局变量
void func1()
{
static int count; //静态局部变量
count++;
int i=count % 10; //局部变量
cout<<"count % 10="<<i<<endl; //"count % 10="为字符串常量
}
void func2()
{
int i=0; //局部变量
int *pi=&i; //局部变量
*pi=*pi+1;
cout<<"i="<<i<<endl; //"i="为字符串常量
}
int main()
{
static int out=2; //静态局部变量
cout<<"out="<out<<endl;
func1();
func2();
return 0;
}
这是内存变量图:
对于一个 C++程序,它的内存模型分成这样几个区域,
text
,rodata
,data
,bss
,heap
,stack
和命令行参数(环境变量)
- rodata 和 text 在同一个段内,称为常量区,只能读,不能写
- data 和bss会在同一个段内,称为全局区,可读可写
rodata
read only data, 上述程序中的pi
和常量字符串count % 10
在这个区域
text
保存编译连接后生成的机器代码,调用函数后加载到栈中执行.
这两个区域称为静态区,只能读不能改.
data
存放已经初始化的全局变量和声明为 static 的局部变量,
static int out=0; //静态全局变量
int i=1; //初始化了的全局变量
static int out = 2; //静态局部变量
这三个, 已经初始化的全局变量和局部变量会存放在 data
区,这里有两个 out, 编译器不会混淆他们的.
bss
block started by symbol.
存储没有初始化的全局变量和 static 的局部变量, 默认先赋值为0(数值)或者 NULL(指针),上文中的
int j; //未初始化的全局变量
static int count; //静态局部变量
都是典型
区分已经初始化和没有初始化的原因是为了节省空间,
在目标文件中, bss 中的变量不占有空间,只保存了他们运行时要占空间的大小,运行时开辟,全部置为0.
data 和 bss 保存的是全局变量和静态局部变量,在程序启动的时候,他们被放入全局区,可读可写
heap
分配动态内存,比如 new
和malloc
内存管理由用户来解决
容易碎片化
一般不会溢出
stack
保存参数和函数内声明的非static 局部变量.
大小有限,容易溢出.
网友评论