内存管理——malloc

        要想使用malloc,至少要经过两步:

        第一   建立线性内存空间管理表,将线性内存分成若干个段,除开一些特殊的段外,存在一些自由的段;

        第二   从自由段中抽取一块作为堆,堆初始化后,就可以通过malloc函数申请变量的存储空间了。

        堆可以有多个,,共享系统程序空间应建立至少一个堆,进程中也可以建立多个。   

        malloc函数应给定堆的指针

void *mem_heap_create(PMEMORY_BASIC_INFORMATION  pMBI ,DWORD  flOptions, SIZE_T dwInitialSize, SIZE_T dwMaximumSize)
{
	void* heap;
	PMEM_CONTROL_BLOCK mcb;
	heap=mem_virtual_alloc(pMBI,0,dwInitialSize,MEM_COMMIT,PAGE_EXECUTE_WRITECOPY);
	print_farmat_msg("mem_heap_create: %x,%x \n",heap,dwInitialSize);

	//设置堆的头部参数,current_blocksize整个堆的大小
	mcb = (PMEM_CONTROL_BLOCK)heap;
	mcb->is_available = 0;
	mcb->prior_block = (void*)-1;	//标识堆头
	//mcb->current_blocksize =dwInitialSize ;
	mcb->heap_end=(DWORD)heap+dwInitialSize;
	mcb++;
	//第一个块
	mcb->is_available = 1;
	mcb->prior_block = heap;	//标识第一块
	mcb->current_blocksize =(dwInitialSize - (sizeof(MEM_CONTROL_BLOCK)+ sizeof(MEM_CONTROL_BLOCK)));
	return heap;

}
//从堆中分配内存
void *mem_heap_alloc(HANDLE hHeap,   DWORD  dwFlags,  SIZE_T dwBytes)
{//lb 0x80404843
	//unsigned int current_location;
	int use_size;
	void * return_pointer = 0;
	/* 这与current_location相同,但转换为memory_control_block */
	PMEM_CONTROL_BLOCK current_mcb = NULL;
	PMEM_CONTROL_BLOCK other_mcb = NULL;
	_ALIGN(dwBytes,4);
	 /* variable用于保存返回值并设置为0,直到我们找到合适的值 */

	// 从托管内存开始搜索
	current_mcb = hHeap+sizeof(MEM_CONTROL_BLOCK);

	 use_size=dwBytes+sizeof(MEM_CONTROL_BLOCK);
	 //遍历所有块,找到合适的空闲块
	while((DWORD)current_mcb <((PMEM_CONTROL_BLOCK) hHeap)->heap_end)
	{

	   //判断当前区块是否可用 ,不可用查找下一个,当前块未被使用
	   if(current_mcb->is_available)
	   {
		//	print_farmat_msg(" %d %d",current_mcb->current_blocksize,dwBytes);
		   //判断当前块大小是符合需要
		   if(current_mcb->current_blocksize<dwBytes)
		   {
			   //1、当前块小于需要量,查找下一个
			   goto nextblock;
		   }
		 else
		 {
			 //2、大小正合适,直接将当前地址返回
			 //3、当前块大于需要量,但分割后的空间小于或等于MEM_CONTROL_BLOCK结构,则将当前的块全部分给当前块
			 current_mcb->is_available = 0;
			 return_pointer = (void *)((DWORD)current_mcb + sizeof(MEM_CONTROL_BLOCK));
			// print_farmat_msg("  %d",current_mcb->current_blocksize - use_size);
			 if((current_mcb->current_blocksize - use_size) >sizeof(MEM_CONTROL_BLOCK))
			 {
				   // 4、当前量大于需要量大小满足申请量且分割后的空间能建立新的块,则分割剩余空间

				 other_mcb=(PMEM_CONTROL_BLOCK)((DWORD)current_mcb+use_size);
				 other_mcb->current_blocksize=current_mcb->current_blocksize-use_size;
				// print_farmat_msg("  %d\n", other_mcb->current_blocksize);
				 other_mcb->is_available=1;
				 other_mcb->prior_block=current_mcb;
				 current_mcb->current_blocksize=dwBytes;
			   }
			 break;
		   }
	   }

	   nextblock:
	   //下一块
	   current_mcb=(PMEM_CONTROL_BLOCK)(sizeof(MEM_CONTROL_BLOCK)+current_mcb->current_blocksize+(DWORD)current_mcb);

	}
	//print_farmat_msg("mem  %x,%d \n ",return_pointer,dwBytes);
	return return_pointer;
}

BOOL mem_heap_free_block(HANDLE hHeap,DWORD dwFlags,LPVOID lpMem)
{
	PMEM_CONTROL_BLOCK current_mcb,next_mcb,prior_mcb,Phead;
	PMEM_CONTROL_BLOCK other_mcb = NULL;
	print_farmat_msg(" free %x",lpMem);
	current_mcb = lpMem-sizeof(MEM_CONTROL_BLOCK);
	//重复释放、判决是否在堆的范围
	if (current_mcb->is_available) return false;
	current_mcb->is_available=1;
	prior_mcb	=current_mcb->prior_block;
	next_mcb=lpMem+current_mcb->current_blocksize;

	//当前是不是最后一块,判断技巧,下一块的内容位置<PHeapEndAddress(存在的比头部位置还小,) 则后面还有块
	//且后块未分配 则合并
	if((((DWORD)next_mcb+sizeof(MEM_CONTROL_BLOCK))<Phead->heap_end)&(next_mcb->is_available))
	{
		current_mcb->current_blocksize+=next_mcb->current_blocksize+sizeof(MEM_CONTROL_BLOCK);
	}
	// 当前是不是第一块,且前块未分配 则合并
	if((current_mcb->prior_block!=hHeap)&(prior_mcb->is_available))
	{
		prior_mcb->current_blocksize+=current_mcb->current_blocksize+sizeof(MEM_CONTROL_BLOCK);
		//后一块不是最后
		if((DWORD)next_mcb+sizeof(MEM_CONTROL_BLOCK) < Phead->heap_end)
			next_mcb->prior_block=current_mcb->prior_block;
	}
	return true;
}



void * kr_malloc(DWORD numbytes)
{
	void *p=mem_heap_alloc(PHeapHeadAddress,0,numbytes);
	//print_farmat_msg("kr_malloc: %d,%x \n ",numbytes,p);
	return p;
}

   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麻雀123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值