C\C++内存管理new/malloc/calloc/realloc

首先,C\C++中程序内存区域划分如下图:
在这里插入图片描述
1.即堆栈, 非静态局部变量/函数参数/返回值存放,向下增长
2.内存映射段是高效的I/O映射方式,用于转载一个共享的动态内存库,可以使用系统接口创建共享内存,做进程间通讯
3.用于程序运行时的动内存分配,向上增长
4.数据段 : 存储全局数据和静态数据
5.代码段可执行代码/只读常量

C语言动态内存管理(malloc/calloc/realloc和free)
malloc/calloc/realloc的共同点:

  1. 都是在堆上创建用于程序运行时的动态内存分配,堆向上增长
  2. 在程序运行结束时,都需要手动释放空间
  3. 在调用函数时,需要强制类型转换
  4. 在函数调用结束(内部才能分配结束后),进行判空
  5. 都是C标准库函数,#include <stdlib.h>/#include<malloc.h>

malloc/calloc/realloc的不同点:
malloc
申请空间大小需要手动计算
eg : int* p = (int*) malloc(4sizeof(int));
申请后的空间时随机值
calloc
在申请空间大小时不需要手动计算
eg :int * p = (int
) calloc(4,sizeof(int))
申请后将空间的值挨个初始化为0
realloc
用于对内存空间进行扩容:
如果原内存空间足够大,系统将会在原内存空间的后面直接扩容,并且直接返回原内存空间的地址
如果原内存空间不够,系统将会重新申请一块内存(大小:原来与现在的和),把原来空间的数据拷贝到新的空间,将原来的空间释放.

C++内存管理new/delete
操作内置内型

void TestNew()
{
	//动态申请一个int的空间
	int* ptr = new int;

	//动态申请一个int类型的空间并且初始化
	int* ptr1 = new int(5);
	
	//动态申请5个int的类型
	int* ptr2 = new int[5];
	
	delete ptr;
	delete ptr1;
	delete pre2[];
}

new和delete配套使用;new[]和delete[]配套使用

操作自定义类型

class Test
{
public:
	Test()
		: _data(0)
	{
		cout<<"Test():"<<this<<endl;
	}
	~Test()
	{
		cout<<"~Test():"<<this<<endl;
	}
private:
	int _data;
};
void Test2()
{
	// 申请单个Test类型的空间
	Test* p1 = (Test*)malloc(sizeof(Test));
	free(p1);
	// 申请10个Test类型的空间
	Test* p2 = (Test*)malloc(sizoef(Test) * 10);
	free(p2);
}
void Test2()
{
	// 申请单个Test类型的对象
	Test* p1 = new Test;
	delete p1;
	// 申请10个Test类型的对象
	Test* p2 = new Test[10];
	delete[] p2;
}
//在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。

operator new 和operator delete
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间
operator new 实际也是通过malloc来申请空间,如果malloc申请空间
成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的
如果申请内存失败了,这里会抛出bad_alloc 类型异常

一个只能在堆上创建对象的类

//该类只能在堆上创建对象
class HeapOnly
{
public:
	static HeapOnly* CreateObject()
	{
		return new HeapOnly;
	}
	
private:
	HeapOnly() {}

	//C++98
	//1.只声明,不实现, 声明成私有
	//2.声明成私有
	HeapOnly(const HeapOnly&);

	//C++11
	HeapOnly(const HeapOnly&) = delete;
};

一个只能在栈上创建对象的类


//该类只能在栈上创建对象

class StackOnly
{
public:
	static StackOnly CreateObject()
	{
		return StackOnly();
	}
private:
	StackOnly() {}
};
//即不能在堆上创建,因此只要将new的功能屏蔽掉即可,即屏蔽掉operator new和定位new表达式,注意:屏蔽了operator new,实际也将定位new屏蔽掉。
class StackOnly
{
public:
	StackOnly() {}
private:
	void* operator new(size_t size);
	void operator delete(void* p);
};

单利模式

//单例模式:
//一个类只能创建一个对象,即单利模式,该模式可以保证系统中该类只有一个实例
//并提供一个访问它的全局访问点,该实例被所有程序模块共享
//单利模式有两种实现方式:
//饿汉模式: 
//优点: 简单
//缺点: 可能会导致程序启动慢,且如果有多个单利类对象实例启动顺序不确定
class singleton
{
public:
	static singleton* GetInstance()
	{
		return &m_instance;
	}
private:
	singleton(){};

	singleton(singleton const&) = delete;
	singleton& operator = (singleton const&) = delete;

	static singleton m_instance;
};
singleton singleton::m_instance;//在程序入口前完成单利对象的初始化


//懒汉模式
//如果单例对象构造十分耗时或者占用很多资源,比如加载插件,等.
//为避免程序启动过慢,可使用懒汉模式(延迟加载)
//优点: 第一次启动实例对象时,创建对象,进程启动无负载,多个单例对象启动顺序自由控制

class Singleton
{
public:
	static Singleton* GetInstance()
	{
		if (nullptr == m_Instance)
		{
			m_mtex.lock();
			if (nullptr == m_Instance)
			{
				m_Instance = new Singleton();
			}
			m_mtex.unlock();
		}
		return m_Instance;
	}

	//内嵌垃圾回收类
	class CGarbo
	{
	public:
		~CGarbo()
		{
			if (Singleton::m_Instance)
			{
				delete Singleton::m_Instance;
			}
		}
	};

	// 定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数从而释放单例对象
	static CGarbo Garbo;
private:
	//构造函数私有
	Singleton(){};

	//防拷贝
	Singleton(Singleton const&);
	Singleton& operator=(Singleton const&);

	static Singleton* m_Instance;//单利对象指针
	static std::mutex m_mtex;
};

一次申4G空间
#include
using namespace std;
int main()
{
void* p = new char[0xfffffffful];
cout << “new:” << p << endl;
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值