内存分配方式介绍-面试最喜欢问的东西

前言

关于内存分配方式,这可是面试官最喜欢问的问题了。前几天笔试一家公司的我也被问到了这样的问题。难么?朋友,肯定不难,咱们今天就把malloc,free,new,delete以及内存分配方式都讲清楚(我尽力吧)

跑偏了

看了别人的回答我才发现,原来内存分配表示的是静态存储区域、栈和堆。。。。。。我丢,看来是真的跑偏了。没事儿,咱们重温一下这仨东西。

静态存储区

比如一些全局变量,或者是static静态变量,在程序编译的时候就已经确定下来了,然后也开辟了内存给他们用,程序结束后系统帮我们释放。初始化的全局or静态变量放在一起,未初始化的全局和静态放在另一块地方(BSS段了解一下?)

栈区

比如函数中定义的局部变量,函数的参数值,都可以是在栈中。栈大小一般比较小,当然VS里可以设置,将原本的1M或者2M设置成更大。

堆区

就很自由了,也叫动态内存区。咱们自己开辟内存,管理内存,释放内存。如果咱们自己申请了内存但是没释放,可能造成内存泄漏。另外如果堆内存管理的不好,可能造成内存碎片。

我当时是怎么回答的

僵硬了,我当时没想到居然是这么个简单的回答,我回答成,堆区的内存管理方式了(内存堆和内存池)。那也没关系,咱们这里就将内存管理的方式给大家介绍一下。

传统的malloc free / new delete方式

先给各位扯明白这两组的区别:
1.malloc free是库函数,new delete是关键字
2.malloc free需要指定分配大小,new delete根据分配类型确定
3.malloc分配失败返回NULL,new分配失败返回bad_alloc
4.new不仅申请内存,还执行对象的构造(delete是析构)函数
5.存放的地方不同。malloc是在堆上,new是在free store上(堆是操作系统级别的东西,free store是语言级别的),如果我开发c++,那么我可以将free store设置成堆,我当然也可以设置成静态存储区。(当然咱们现在是new在堆上,所以存放地址没啥区别)

咱们一起看看,malloc是如何实现堆内存管理的。
其实说白了,就是在一段连续的内存地址上,将已经分配的和没有分配的内存都用一个mem_ctrl_block这样的struct来管理。咱们现在自己来实现一个malloc,叫myMalloc,开始:

struct mem_heap_head
{
   
	bool IsFreeData;
	long MemHeapDataLength;
};

void* memory_heap_start;
void* memory_heap_end;

下面是一些基本的操作:

//private:将数据部分地址转换成对应的控制字首部指针
void* ToHeadPtr(void* addr)
{
   
	if (addr == nullptr)
		return nullptr;
	struct mem_heap_head* addrHead;
	addrHead = (struct mem_heap_head*)((char*)addr - sizeof(struct mem_heap_head));
	return (void*)addrHead;
}

//private:判断控制字首部指针是否指向heap末尾
bool IsPtrEndOfHeap(void* ptr)
{
   
	struct mem_heap_head* head = (struct mem_heap_head*)ptr;
	if (head == (struct mem_heap_head*)memory_heap_end)
		return true;
	else
		return false;
}

//private:最小插入一帧(头部+数据部分)大小
int MinSizeOfFrame(size_t size)
{
   
	return size + sizeof(struct mem_heap_head);
}

//private:输入当前控制字地址和数据部分长度,给出下一个控制字地址
void* ToNextPtr(void* addr, size_t size)
{
   
	if (addr == nullptr)
		return nullptr;
	return (struct mem_heap_head*)((char*)addr + MinSizeOfFrame(size));
}

void MyMemoryHeapFree(void* addr)
{
   
	//1.先根据addr找到对应的struct地址,地址是有小到大的
	struct mem_heap_head* addrHead;
	addrHead = (struct mem_heap_head *)ToHeadPtr(addr);
	addrHead->IsFreeData = false;
}

void* MyMemoryHeapMalloc(size_t size)
{
   
	//采用fast fit方式快速找到待分配的内存,同时完成内存碎片的优化
	struct mem_heap_head* head = (struct mem_heap_head*)memory_heap_start;
	while (IsPtrEndOfHeap(head) == false)
	{
   
		if (head->IsFreeData == true)
		{
   
			if (MinSizeOfFrame(size) <= head->MemHeapDataLength)	//需要对这一个内存块进行划分
			{
   
				struct mem_heap_head* nextHead = (struct mem_heap_head*)ToNextPtr(head
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值