C++入门-->初识内存管理

前言:本篇主要解释了C/C++中动态申请/释放内存的方式,以及C++和C语言中中申请内存方式的相同/异点。

C语言的动态申请内存的方式:

  1.malloc: 以int为例-->

int * arr = (int*)malloc(sizeof(int) * 10);

在C语言中我们知道使用malloc申请的内存是未初始化的,还需要我们手动来初始化:

int * arr = (int*)malloc(sizeof(int) * 10);
for (int i = 0; i < 10; i++)
{
	*arr = i;
	cout << *arr << " ";//打印测试
	++arr;
}

2.calloc,以int为例子-->

int* newSpace = (int*)calloc(sizeof(int) * 10, 0);

很明显,calloc支持将申请后的内存初始化赋值

3.realloc,以int为例子-->

int* Space = (int*)malloc(sizeof(int) * 5);
int* newSpace = (int*)realloc(Space,sizeof(int)*10);

realloc可以扩容一块已经申请的内存,具体细节C语言相关帮助文档有详细说明:std::realloc - C++中文 - API参考文档 (apiref.com)

上述三种当时申请的内存在C语言中都是通过free释放的:

free(arr);
free(newSpace);

上述三个动态申请内存的函数在处理内置类型固然还可以,但是当涉及到自定义类型时,就显得有些乏力了所以C++引入了新的内存申请方式-->new.delete

new:

先来看看new申请内置类型的内存,以int类型为例:

/*只申请内存,不初始化*/
int* Space1 = new int;
/*申请内存后并初始化值*/
int* Space2 = new int(1);
/*申请连续的空间*/
int* Space3 = new int[5];
/*申请连续的空间并赋值*/
int* Space4 = new int[5] {1,2,3,4,5};

delete,以上述为例,用来释放new出来的内存.

/*只申请内存,不初始化*/
int* Space1 = new int;
/*申请内存后并初始化值*/
int* Space2 = new int(1);
/*申请连续的空间*/
int* Space3 = new int[5];
/*申请连续的空间并赋值*/
int* Space4 = new int[5] {1,2,3,4,5};

delete Space1;
delete Space2;
delete Space3;

/*释放连续的内存要使用delete[]*/
delete[] Space4;

new和delete对于C++的自定义类型(类):

简单来说,在申请自定义类型的空间时,new会调用自定义类型的构造函数,delete会调用自定义类型的析构函数,这在c语言中的内存申请函数无法做到的。

示例:

class newTestClass
{
public:
	newTestClass(int data = 0)
		:_data(data)
	{
		/*测试打印看会出现什么现象?*/
		cout << "调用newTestClass的构造函数" << endl;
	}
	~newTestClass()
	{
		_data = 0;
		/*测试打印看会出现什么现象?*/
		cout << "调用newTestClass的析构函数" << endl;
	}
private:
	int _data;
};
int main()
{
	newTestClass* space = new newTestClass;
    delete space;
	return 0;
}

结果很显而易见-->

同样的,如果要申请连续的自定义类型的空间,使用new _type[],释放使用delete[] + _type

使用malloc/calloc/realloc均不会自动调用自定义类型的构造和析构函数!

operator new operator delete 函数:
解释: operator new 和operator delete是 系统提供的 全局函数 new在底层调用operator new全局 函数来申请空间, delete在底层通过 operator delete 全局函数来释放空间
1.浅谈类中的operator new 和 operator delete
直接上代码:
class newTestClass
{
public:
	newTestClass(int data = 0)
		:_data(data)
	{}
	void* operator new(size_t size)
	{
		//
	}
	void operator delete(void* ptr)
	{
		//
	}
	~newTestClass()
	{
		_data = 0;
	}
private:
	int _data;
};

如果类中重载了new,那么当new这个类类型的对象时,会自定调用该类中重载的operator new来申请内存。

2.浅谈全局的operator new.operaotr delete:

copy了一份源码:

void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
	// try to allocate size bytes
	void* p;
	while ((p = malloc(size)) == 0)
	{
		if (_callnewh(size) == 0)
		{
			// report no memory
			// 如果申请内存失败了,这里会抛出bad_alloc 类型异常
			static const std::bad_alloc nomem;
			_RAISE(nomem);
		}
	}
	return (p);
}
void operator delete(void* pUserData)
{
	_CrtMemBlockHeader* pHead;
	RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
	if (pUserData == NULL)
		return;
	_mlock(_HEAP_LOCK);
	__TRY
		pHead = pHdr(pUserData);
	_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
	_free_dbg(pUserData, pHead->nBlockUse);
	__FINALLY
		_munlock(_HEAP_LOCK);
	__END_TRY_FINALLY
		return;
}

operator new 实际是通过封装了malloc来申请空间。operator delete 最终是通过free来释放空间的,入门阶段了解一下即可。
内存泄露的讨论;
内存泄漏很危险!!!!!,当你动态申请了内存之后,不用了一定要记得释放该内存,不然就会造成内存泄漏。
内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现
内存泄漏会导致响应越来越慢,最终死机!!!!
  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值