new和delete操作符
C++通过new和delete操作符进行动态内存管理
new/delete操作内置类型
申请和释放单个元素的空间,使用new和delete操作符。申请和释放连续的空间,使用new[]和delete[]。
new/delete操作自定义类型
class A
{};
void test()
{
A* p1 = new A;//申请单个A类型的对象
delete p1;
A* p2 = new A[5];//申请5个A类型的对象
delete[] p2;
}
申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会
设计一个类,只能在堆上创建对象
将类的构造函数私有,拷贝构造声明成私有。防止别人调用拷贝在栈上生成对象。
提供一个静态的成员函数,在该静态成员函数中完成堆对象的创建
class HeapOnly
{
public:
static HeapOnly* CreateObject()
{
return new HeapOnly;
}
private:
HeapOnly() {}
HeapOnly(const HeapOnly&);
};
设计一个类,只能在栈上创建对象
只能在栈上创建对象,即不能在堆上创建,因此只要将new的功能屏蔽掉即可,即屏蔽掉operator new和定位new表达式,注意:屏蔽了operator new,实际也将定位new屏蔽掉
class StackOnly
{
public:
StackOnly() {}
private:
void* operator new(size_t size);
void operator delete(void* p);
};
单例模式
设计模式是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。
单例模式:
一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
饿汉模式
不管将来用不用,程序启动时就创建一个唯一的实例对象
优点:简单
缺点:可能会导致进程启动慢,且如果有多个单例类对象实例启动顺序不确定
懒汉模式
延迟加载
优点:第一次使用实例对象时,创建对象。进程启动无负载,多个单例实例启动顺序自由控制
缺点:复杂
内存泄漏
内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费
内存泄漏分类
- 堆内存泄漏:堆内存指的是程序执行中依据须要分配通过malloc / calloc / realloc / new等从堆中分配的一块内存,用完后必须通过调用相应的 free或者delete 删除
- 系统资源泄漏:指程序使用系统分配的资源,比方套接字、文件描述符、管道等没有使用对应的函数释放掉,导致系统资源的浪费
解决方案
- 事前预防型,如智能指针
- 事后查错型,如泄漏检测工具
如何一次在堆上申请4G的内存
#include <iostream>
using namespace std;
int main()
{
void* p = new char[0xfffffffful];
cout << "new:" << p << endl;
return 0;
}