首先,程序都是在内存中运行的,故而堆栈都处在内存里。

内存中包括:栈区、堆区、静态、静态存储区、文字常量区、程序代码区五个

其中:

!()[“C:\Users\14742\Desktop\blog\public\img\内存五区.png”]

1.栈区:执行函数的时候,函数内部(包括main函数)的局部变量都在栈区创建,程序结束时由程序自动释放。

这种栈内存分配的相关运算是由cpu的寄存器来存取的,效率高,但分配空间有限(但不是分配在寄存器上,别混淆,寄存器只是一个媒介),只有几MB,可以通过编译器选项修改。

2.堆区:

堆区就由程序员手动分配的存储区,使用malloc(),new等函数分配,free delete等函数释放,优点是灵活,代价是容易被程序员遗忘释放操作。未释放的内存在程序结束时由系统收回。

3.静态区/全局区/全局静态区/静态全局区:

细分为:data区,bbs区,常量区

    ①全局变量和静态变量是放在一起的

    ②初始化的全局变量和静态变量放在一个区:data segment

    ③未初始化 的放在相邻的另一个区: bss(block started by symbol)。 该区在编译好的目标文件中不被分配内存,只是记录所需要的大小。

    为什么要将初始化和未初始化的变量分别存放在两个区:

      a. 内存是否被分配的区别

      b. 未初始化的放在bss区,在程序启动时可以统一调用memset,将为初始化的统一初始化为0或NULL。(注意:只是全局区未初始化对象会调用,栈区的不会,栈区对象未初始化会直接报错

针对静态对象:

由static声明变量,对应.c(cpp)文件,函数内部,class类的静态处理产生了三种静态对象:

①全局静态对象:对应.c(cpp)文件的静态

②局部静态对象

③class静态成员

对这三种对象处理:都是第一次运行时创建,程序结束时销毁

4.(文字)常量区:顾名思义就是存储文字常量的地方,存放常量(程序在运行的期间不能够被改变的量,例如: 10,字符串常量”abcde”, 数组的名字等)

问题:到底哪些常量是存放在常量区的呢,如果在函数内定义一个变量的时候,变量赋的值(比如 5这个数),这个5是放在栈区的内存上还是放在常量区

文字常量不可寻址(&),除非转化为常变量

1
const int& r=5

在数据区开辟一个值为5的无名整型常变量

5.程序代码区:

存放常量字符串,程序退出后由OS释放

经典实例:(代码来自网络高手,没有找到原作者)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <string> 

int a=0; //全局初始化区
char *p1; //全局未初始化区
void main()
{
int b;//栈
char s[]="abc"; //栈
char *p2; //栈
char *p3="123456"; //123456\0在常量区,p3在栈上。
static int c=0; //全局(静态)初始化区
p1 = (char*)malloc(10);
p2 = (char*)malloc(20); //分配得来得10和20字节的区域就在堆区。
strcpy(p1,"123456"); //123456\0放在常量区,编译器可能会将它与p3所向"123456\0"优化成一个地方。
}

缓存、内存、缓冲区

①缓存包括程序缓存cpu缓存

程序缓存就是缓冲区,包括内存的栈区和堆区

③CPU缓存:这是硬件层次缓存,处于内存条和CPU之间,以为比如CPU的L1 L2 L3等缓存机制,因为CPU缓存比CPU读内存数据更快!用于存放热点数据,数据如何分级存放有自己的算法。