C++程序的内存布局

一个C/C++源程序经过编译之后,其应用程序使用的内存可划分为一下几个部分:

1)代码区

代码区存放函数体的二进制代码。可执行文件加载之后,就存放在进程的代码区。这部分分区域是只读的,如果试图修改,将导致运行时错误。一般来说,程序的代码区存放的是程序的可执行代码,在某些特殊情况下,一些重要的数据也可以放入代码区,以防止错误修改。

2)栈区

程序中用来存放函数的参数值、局部变量、临时变量。由编译器生成的代码自动完成内存的分配与释放,操作类似于数据结构中的栈。windows下,栈是一块由高地址向低地址方向生长的空间。在程序运行时,只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常,提示栈溢出。除非特别指定,C++程序运行时,栈的最大容量是系统预先规定好的。

#include"pch.h"
#include<iomanip>
#include<iostream>
using namespace std;

int *addr;
int cnt;

//每次调用函数时,会把参数先压栈,所以使用 addr-&i 就可以知道一次递归调用耗费多少内存
void func(int i) { 
	cout << cnt << ":" << (int)addr - int(&i) << endl;
	cnt++;
	addr = &i;
	func(i);
}

int main() {
	int i;
	addr = &i;
	func(2);
}

运行结果:

内存溢出

所以一个进程可以使用的内存大小大概是:4756*216/1024 = 1003K,大约1M。

3)堆区

供程序员动态申请和释放空间的内存区。这个区域由程序员自己负责维护。

堆的具体实现和管理方式与操作系统相关,不同操作系统的实现细节是不同的。一般原理:在操作系统中设置一个记录空闲内存地址的链表,当系统收到程序的申请时,遍历该链表,寻找第一个空间大于申请空间的堆节点。然后将该节点从空闲节点链表中删除,并将该节点的空间分配给程序。而且一般会在这块内存空间中的首地址处记录本次分配的大小,以便代码中的delete语句能够正确地释放本内存空间。由于找到的堆节点大小不一定等于申请的大小,系统会自动地将多余的那部分重新放入空闲链表中。

4)全局/静态区

用来存放全局变量和静态变量的内存区。程序在创建这块存储区时会自动将所有字节清0.所以如果没有显示地位全局(静态)变量赋初始值,那么它的初始值就是0.程序结束之后由系统释放。

5)常量区

用于存放字符串常量的内存区。程序运行结束后由系统自动释放。

常量区既不是存放文字常量(存放在代码区),也不是存放常变量(存放在栈区或堆区)的存储区。常量区里存放的是字符串常量,以及一些在程序运行中不能修改的重要数据(比如类的虚函数表等)。常量区是只读的,如果试图修改,将导致运行时错误。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值