什么是物理内存与虚拟内存:
- 物理内存:在应用中,真实存在的,插在主板内存槽上的内存条的容量的大小。从本质上来说,物理内存是代码和数据在其中运行的窗口。
- 虚拟内存:使程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。进程在运行的时候,操作系统都为其分配一个4GB的地址空间,即所谓的虚拟地址空间。
c++如何管理动态内存:
- new/delete 动态管理对象
- new[]/delete[] 动态管理对象数组
#include <iostream>
#include <windows.h>
using namespace std;
int main()
{
int *p1 = new int;//动态分配4字节
int *p2 = new int(3);//动态分配4字节
int *p3 = new int[3];//动态分配12字节
int *p4 = (int*)malloc(sizeof(int));
delete p1;
delete p2;
delete[] p3;//对象数组
free (p4);
system("pause");
return 0;
}
注意:malloc/free,new/delete,new []/delet e[]一定要配套使用!
否则会出现内存泄露或崩溃的问题。
接下来复习一下内存先:
找找下面代码中各变量在内存中的什么位置?
1 #include <iostream>
2 using namespace std;
3
4 int s1=1;//数据段
5 static int s2=2;//数据段
6 int main()
7 {
8 static int s3=10;//数据段
9
10 char *p1="abcd";
11 //p1存在于栈,*p1存在于代码段
12 char p2[]="efgh";
13 //数组 p2->栈,*p2-》栈
14 int *p3=(int*)malloc(sizeof(int));//堆
15
16 int *p4=new int;//堆
17 int *p5=new int[3];//堆
18
19 free (p3);
20 delete p4;
21 delete[] p5;
22 return 0;
23 }
malloc/free与new/delete的区别与联系?
- 均为动态管理内存入口;
- malloc/free是c/c++标准库函数,new/delete是c++操作符;
- malloc/free是动态分配内存/释放内存,new/delete除了分配空间还会调用构造函数与析构函数进行初始化与清理。
- malloc需手动计算类型大小且返回值为void*,new可自主计算类型大小,返回对应类型的指针。
- malloc失败返回0,new失败返回异常
对上述理论部分的解释:
class Array
{
public:
Array(size_t size = 10)
:_size(size)
, _a(0)
{
cout << "Array()" << endl;
if (_size > 0)
{
_a = new int[size];
}
}
~Array()
{
cout << "~Array()" << endl;
if (_a)
{
delete[] _a;
_a = 0;
_size = 0;
}
}
private:
int *_a;
size_t _size;
};
void Test()
{
Array* p1 = (Array*)malloc(sizeof(Array));
//Array* p2 = new Array;
//Array* p3 = new Array(20);
Array* p4 = new Array[4];
//使用new时先创建空间再调用构造函数,释放时先调用析构函数再delete。
//创建几个调用几次
free(p1);
//delete p2;
//delete p3;
delete[] p4;
}
c++的其他内存管理接口
- void* operator new (size_t size);
- void operator delete(size_t size);
- void* operator new[](size_t size);
//该类函数没有重载new与delete表达式
总结:
1. operator new /operator delete operator new []/operator delete[] 和 malloc /free用法一样。
2. 他们只负责分配空间/释放空间,不会调用对象构造函数/析构函数来初始化/清理对象。
3. 实际 operator new /operator delete 只是malloc和free的一层封装。
那么new做了什么呢:
- 使用operator new创建空间
- 调用构造函数初始化对象
delete呢:
- 调用析构函数清理对象
- 使用operator delete 释放空间
new[N]
- 调用operator new分配空间.
- 调用N 次构造函数分别初始化每个对象。
delete[N]
- 调用N 次析构函数清理对象。
调用operator delete释放空间
具体过程如下: