计算机组成
硬件:CPU,内存条,磁盘,键盘,鼠标,网卡等 软件:操作系统OS OS目前主要由汇编及C语言编写,有大量的C语言 通常调用OS的接口,实际就是调用C语言的接口 后续安装/运行的软件都运行在OS上
虚拟内存
一台电脑可以安装多个内存条,在OS中将这些内存条统计编码 形成一个由0,1,2,... 开始的位置编码,这就是虚拟内存 比如,4个16G的内存条,在电脑中的虚拟内存是64G
进程使用的内存
一个命令或软件运行时,会启动一个进程 OS为每个进程开辟一个虚拟内存,地址都从0开始 但整个OS只有一个虚拟内存,由其他程序控制其使用的位置不冲突,比如 进程1使用了虚拟内存200-800,64G-63G,位置的地址, 进程2使用了虚拟内存1000-2000,63G-62G位置的地址... 所以,你在电脑上运行任何一个软件,它能使用的内存范围都是0到整个电脑的内存
进程的内存结构
从左到右,虚拟内存地址从低到高依次是 代码区,数据区,堆,栈 代码区:数据代码,不可变, 数据区:编辑阶段初始化变量的数据,比如静态变量,全局变量等 堆:C语言中使用malloc/calloc,C++中使用new分配的空间,地址从低向高增加, 堆在低位,栈在高位 栈:也叫堆栈,除了前面三个外,剩下所有的变量都分配在栈里,地址从高向低增加,先进后出,后进先出
C++内存结构
OS就是C/C++写的,因此C++的内存结构与进程的内存结构差不多
#include <iostream> int c ; int aa(){ int a = 3; } int main(){ int b; return 0; }
a,b存储在栈上 c是全局变量,存储在数据区
C++自动存储就是栈存储,自动释放
栈存储的变量数值存储在栈上,特点是定长, 虚拟地址一个格格是一个字节,Int这种4字节的,需要指针跳4个格格, 这里就是在栈上跳4个位置,从高向低位跳
从高向低的位置分配
#include <iostream> int main(){ int a = 1; int b = 2; int* p1 = &a; int* p2 = &b; std::cout << "p1" << "=" << p1 << std::endl; std::cout << "p2" << "=" << p2 << std::endl; return 0; } $ g++ e.cpp $ ./a.out p1=0x7ffd37d7e03c p2=0x7ffd37d7e038 $ ./a.out p1=0x7ffdf405977c p2=0x7ffdf4059778 $ g++ e.cpp $ ./a.out p1=0x7ffde4b1276c p2=0x7ffde4b12768 每次运行就是一个新的进程,但每次p1的地址都比p2的地址位置大,因为p1先分配 并且8~c,从高到低是c~8,按16进制是c,b,a,9 这4个字节, 刚好四个字节一个int,然后就是下一个字节的开始地址8
就单个进程而言,栈这种 后进先出 的结构适合全局处理
new堆上开辟空调,返回的是地址
new 在堆上开辟内存空间,必须与delete配合使用 强调一下,不用new的,统一分配到栈内存上 int* a = new int; *a = 1; //a=0x19d8010 delete a;
C语言中malloc可以分配单个或者一个数组的内存,realloc还可以扩容,由free释放 C++中有类的概念,malloc在为类对象分配空间时无法调用构建函数,free时无法调用析构函数 由于诞生了new与delete malloc是按字节分的,new人性化了一些,不用去管一个类型多少个字节,直接按数据类型分配
C++学习笔记(二):C++变量存储方法 【重学C++】01| C++ 如何进行内存资源管理? c++==与c内存分配释放及引用的对比(3)