C/C++存储区域划分(栈区,堆区,全局区,代码区)

常见的C/C++语言两大版本内存区域分区:
1.五大内存分区:堆、栈、全局/静态存储区、自由存储区和常量存储区。
2. 五大内存分区:堆、栈、全局/静态存储区、字符串常量区和代码区。

因为具体的内存分区与编译器有关,没有太大区别,我们粗略的将程序所占用的内存分为四个区域—栈区,堆区,全局区,代码区.
每个程序都有唯一的四个内存区域.我们需要熟悉和了解各个区域的特性,例如存储什么类型的数据, 有谁去申请开辟, 又有谁去管理释放等等。

一. 内存分配介绍

1.栈区(satck)

由编译器自动分配释放, 存放函数的参数值,局部变量等。主要存放函数的参数以及局部变量。在函数完成执行,系统自行释放栈区内存,不需要用户管理。整个程序的栈区的大小可以在编译器中由用户自行设定,VS中默认的栈区大小为1M,可通过VS手动更改栈的大小。64bits的Linux默认栈大小为10MB,可通过ulimit -s临时修改。
例如: 参数buf,参数bufsize和size都是存放在栈区.当函数执行完毕的时候,自动释放

void  recev(char* buf, int bufsize){
	int size;
}

2. 堆区

一般由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回收。,堆的总大小为机器的虚拟内存大小。
说明:c++中new操作符本质上是使用了malloc进行内存的申请,new和malloc的区别如下:
(1)malloc是C语言中的函数,而new是C++中的操作符。
(2)malloc申请之后返回的类型是void*,而new返回的指针带有类型。
(3)malloc只负责内存的分配而不会调用类的构造函数,而new不仅会分配内存,而且会自动调用类的构造函数。
(4)由new分配的内存块放在堆区,用delete结束生命,由malloc等分配的内存块放在自由存储区,和堆类似,用free来结束生命。
例如:下面的src所指向的内存空间就是在堆区

char* src = (char*) malloc(sizeof(buf) * sizeof(10));

3. 全局区(静态区,static)

全局变量和静态变量存放在此. 里面细分有一个常量区, 字符串常量和其他常量也存放在此,该区域是在程序结束后由操作系统释放。初始化后的全局变量和静态变量放在一个区域(.data段),未初始化的全局变量和未初始化的静态变量放在相邻的另一块区域(.bss段),常量放在另外一块区域(.rodata段)。
注意
(1)静态存储区内的变量若不显示初始化,则编译器会自动以默认的方式进行初始化,即静态存储区内不存在未初始化的变量。
(2)静态存储区内的常量分为常变量和字符串常量,一经初始化,不可修改。静态存储内的常变量是全局变量,与局部常变量不同,区别在于局部常变量存放于栈,实际可间接通过指针或者引用进行修改,而全局常变量存放于静态常量区则不可以间接修改。
(3)字符串常量存储在静态存储区的常量区,字符串常量的名称即为它本身,属于常变量。

4. 程序代码区

这个区域存放函数体的二进制代码.也是由操作系统进行管理的
示例代码:

int a = 0;						//静态全局变量区,.data段
char *p1; 						//编译器默认初始化为NULL,.bss段
const int A = 10;				//常量区(.rodata段)
volatile const int B = 10; 		//.data段
void main()
{
    int b; 						//栈
    char s[] = "abc";			//栈
    char *p2 = "123456";		//123456在字符串常量区,p2在栈上
    static int c = 0; 			//c在静态初始化变量区(.data段),0为文字常量,在代码区
    const int d = 0;			//栈
    static const int d;			//静态常量区(.bss段)
    p1 = (char *)malloc(10);	//分配得来得10字节在堆区。
    strcpy(p1, "123456"); 		//123456放在字符串常量区(.rodata段),编译器可能会将它与p2所指向的"123456"优化成一个地方
}

如下图所示:
在这里插入图片描述

二.划分内存区域的意义

C语言程序中,根据是局部变量,全局变量, 常量还是通过malloc等类似的函数分配内存空间, 把他们放到对应的内存区中.这样就赋予了这些变量或常量不同的生命周期, 不同的释放方式.
根据我们程序的需要,我们在编码过程中,声明不同的变量类型, 使他们有不同的声明长度, 不同的释放方式,给我们更大的灵活编程。

总结

在理解C/C++内存分区时,常会碰到如下术语:数据区,堆,栈,静态存储区,静态区,常量区,常变量区,全局区,字符串常量区,静态常量区,静态变量区,文字常量区,代码区等等,初学者被搞得云里雾里。在这里,尝试捋清楚以上分区的关系。
数据区包括:堆,栈,静态存储区。
静态存储区包括:常量区(静态常量区),全局区(全局变量区)和静态变量区(静态区)。
常量区包括:字符串常量区和常变量区。
代码区:存放程序编译后的二进制代码,不可寻址区。

  • 7
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值