C++中系统内存分区与程序内存分区

释放双眼,带上耳机,听听看~!

在C++中,有内存分成6个区,即系统数据区,自由存储区,文本区(程序代码段),const数据区,全局/静态区,堆区和栈区。
 

系统数据区:存放的是系统数据,我们是不能自由访问的,有时候windows系统会突然弹出一个消息框,内容是“内存不能为read”就是错误访问系统数据区的结果;

自由存储区:用来存放由C延伸而来的 malloc()函数所分配的数据,它和堆十分相似,不过它用free结束自己的生命;

 

文本区(代码区域):存放着我们的函数代码,我们调用函数时的底层行为就类似于先去操作一个指针,而这个指针就指向函数指令所在的地址,也就是在文本区中;

 

const数据区:就是存放不可修改的数据的内存区域,我们定义的const变量都存放在这里。

 

全局/静态存储区:在程序中,全局变量以及由static标号定义的数据都存放在全局静态存储区中,不论是在main()函数之外的定义的全局变量,还是在子函数中定义的局部变量,只要在定义之前有static标号,定义之后就会始终存在于全局静态存储区中。凡是有static定义的变量的生命周期就是整个程序的生命周期,直到程序退出,静态变量所占据的内 存才会被释放。

 

堆存储区:它行为类似于静态存储区,当我们在堆上分配内存之后,如果不进行手动的释放,其内存是不会自动释放掉的。在C++中,如果我们分配了堆内存,就必须手动释放它。否则如果我们不停的分配堆内存,但是不对其进行释放,当对内存被耗尽是就会造成程序崩溃。一般地,用new分配的变量是存放于堆内存中的,但是返回的指针变量是存放在栈中的。当我们在一个子函数中new了一个变量,但是在函数返回时既没有保存 new返回的指针,也没有delete时,就会造成内存泄露。

 

栈区域:也是我们在写程序中用到的最多的情况。程序中定义的每一个临时对象,new所返回的指针,以及递归函数中变量都是存放在栈中的。栈内存是可以自动释放的,当我们在某个模块中定义了一个对象,在该模块结束时,变量所占据的内存就会被系统回收,在定义新的变量时,新的变量就有可能存放在原变量所在的地址上,但是在系统回收栈内存的时候,是不会清空所释放的栈内存中的数据的,只是将栈顶重新调整,并在新数据的到来时将其分配到栈顶。

 

什么是堆:堆是大家共有的空间,分全局堆和局部堆。全局堆就是所有没有分配的空间,局部堆就是用户分配的空间。堆在操作系统对进程初始化的时候分配,运行过程中也可以向系统要额外的堆,但是记得用完了要还给操作系统,要不然就是内存泄漏。

什么是栈:栈是线程独有的,保存其运行状态和局部自动变量的。栈在线程开始的时候初始化,每个线程的栈互相独立。每个函数都有自己的栈,栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动的切换栈,就是切换SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。

实例:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1// 2014525_6.cpp : 定义控制台应用程序的入口点。
2//
3
4#include "stdafx.h"
5
6int a = 0; //全局区
7char *p1;  //全局区
8
9int _tmain(int argc, _TCHAR* argv[])
10{
11  int b; //栈区
12  char s[] = "hello"; //栈区
13  char p2;   //栈区
14  char *p3  = "1234567";  //1234567在常量区域,p3在栈区上
15  static int c = 0;  //全局(静态)区
16  p1 = new char[10];  //在堆区域
17  p2 = new char[20];
18  strcpy(p1, "123456"); //123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
19  int* p3 = new int[5]; //p3在栈,这句话的意思:在栈内存中存放了一个指向一块堆内存的指针p3
20   //在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中
21  return 0;
22}
23
24

给TA打赏
共{{data.count}}人
人已打赏
安全技术

C/C++内存泄漏及检测

2022-1-11 12:36:11

气候事件

6号台风“马鞍”将登陆或擦过日本南部沿海

2011-7-19 16:17:33

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索