一.C/C++内存模型基本概念
1.两大分区:代码区和数据区
2.四大分区:代码区,全局区(全局/静态存储区),栈区,堆区
3.C语言分区:堆,栈,静态全局变量区,常量区
4.C++语言分区:堆、栈、自由存储区、全局/静态存储区、常量存储区(标准答案)
5.C/C++内存模型根据生命周期的不同有三大区:即自由存储区(C++),动态区、静态区
6.代码虽然占内存,但不属于c/c++内存模型的一部分
二.各分区实际内存结构
text段: 用于存放程序代码的区域, 编译时确定, 只读。更进一步讲是存放处理器的机器指令,当各个源文件单独编译之后生成目标文件,经连接器链接各个目标文件并解决各个源文件之间函数的引用,与此同时,还得将所有目标文件中的.text段合在一起,但不是简单的将它们“堆”在一起就完事,还需要处理各个段之间的函数引用问题。
data段 :用于存放在编译阶段(而非运行时)就能确定的数据,可读可写。也是通常所说的静态存储区,赋了初值的全局变量、常量和静态变量都存放在这个域。 (已经初始化的数据)
bss段:不在可执行文件中,由系统初始化。(未初始化的数据)
heap:由程序员分配和释放;若程序员不释放,程序结束时操作系统会进行回收。(malloc,free,new,delete)
stack:存放函数的参数值和局部变量,由编译器自动分配和释放
env:环境变量
三.各大分区的基本介绍
堆 heap
由程序员释放:指的是程序员使用malloc/free,或者new/delete(自由存储区,自由存储区可以理解是堆区的一个子集,不完全等价)申请或者销毁的内存所在的区域。
如果程序员没有释放,在程序运行过程中,可能出现内存泄漏的状况(堆上无用的内存没有及时的销毁free/malloc,程序无法在堆上找到空闲的内存,目前的操作系统通常有虚拟内存技术,每个进程都有可能将整个内存空间完全沾满,这样内存泄漏是非常危险的,会导致其他进程的内存页被换下,会导致大量的缺页中断,最后死机蓝屏)
代码测试:
#include<iostream>
void test1()
{
int *p=new int(1);
printf("test1 p:%p\n",p);
delete p;
}
int main()
{
int *p=new int(1);
printf("main p:%p\n",p);
int *p2=new int(1);
printf("main p2:%p\n",p2);
test1();
delete p;
delete p2;
return 0;
}
分析:我们先在main new了一个p,然后我们new 了一个p2,最后我们调用test函数,new了一个p;
内存分布流程如下
main(*p);
main(*p)->main(p2);
main(*p)->main(p2)->test1(*p);
2.我们改变顺序再次测试:
#include<iostream>
void test1()
{
int *p=new int(1);
printf("test1 p:%p\n",p);
delete p;
}
int mai