SGI STL 内存管理代码[原理参见STL源码剖析]

本文深入探讨了一种用于高效内存管理的内存池实现机制,包括内存分配、释放和复用策略,旨在减少内存碎片,提高内存使用效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//mempool.h
#ifndef _MEM_POOL_H   
#define _MEM_POOL_H   


#include <stdlib.h>






static size_t __freelist_index(size_t bytes);
static size_t __round_up(size_t bytes);


static void mem_init();
static void* mem_malloc(size_t n);
static void mem_free(void* p,size_t n);
static void mem_destroy();
//static void *mem_realloc(void*ptr,size_t newsize,size_t oldsize);


static void *refill(size_t n);
static char *chunk_alloc(size_t size,int *nobjs);


#define __MAX_BYTES 20*1024
#define __ALIGN 512
#define __NFREELISTS __MAX_BYTES/__ALIGN


typedef union obj{
	union obj *free_list_link;
	char client_data[1];
}obj;


obj *free_list[__NFREELISTS];
static char* start_free;
static char* end_free;
static size_t heap_size;


static unsigned long g_addr[__NFREELISTS * 10];
static int g_addr_num=0;


#endif
//mempool.c 
#include <stdio.h>
#include "string.h"
#include "mempool.h"

static size_t __freelist_index(size_t bytes) {
	return (bytes + __ALIGN - 1) /__ALIGN - 1; 
}

static size_t __round_up(size_t bytes){
	return (bytes + __ALIGN - 1) & ~(__ALIGN-1);
}

static void *mem_malloc(size_t n) {
	obj**my_free_list;
	obj* result;
	void *p;

	if(n > (size_t)__MAX_BYTES) {
		p = malloc(n);
		return p;
	}

	my_free_list = free_list + __freelist_index(n);
	result = *my_free_list;
	if(result == NULL) {
		p = refill(__round_up(n));
		return p;
	}
	*my_free_list = result->free_list_link;
	return result;
}

static void mem_free(void*p,size_t n){
	obj* q = (obj*)p;
	obj** my_free_list;
	if(n > (size_t)__MAX_BYTES) {
		free(p);
		return ;
	}
	
	my_free_list = free_list + __freelist_index(n);
	q->free_list_link = *my_free_list;
	*my_free_list = q;
}


static void *refill(size_t n) {
	int nobjs = 20;
	char *chunk = chunk_alloc(n,&nobjs);
	obj** my_free_list;
	obj* result;
	obj* curr_obj,*next_obj;
	int i;
	if(nobjs == 1) return chunk;
	my_free_list = free_list + __freelist_index(n);
	result = (obj*)chunk;
	*my_free_list = next_obj = (obj*)(chunk + n);
	for (i=1;i<nobjs;i++) {
		curr_obj = next_obj;
		next_obj = (obj*)((char*)next_obj + n);
		curr_obj->free_list_link = next_obj;
	}
	curr_obj->free_list_link = NULL;
	
	return result;
}

static char* chunk_alloc(size_t size,int *nobjs) {
	char *result;
	size_t total_bytes = size * (*nobjs);
	size_t left_bytes = end_free - start_free;
	size_t bytes_to_get;
	obj **my_free_list,*p;
	int i;

	if(left_bytes >= total_bytes) {
		result = start_free;
		start_free += total_bytes;
		return result;
	}
	if(left_bytes >= size) {
		*nobjs = (int)(left_bytes/size);
		total_bytes = size * (*nobjs);
		result = start_free;
		start_free += total_bytes;
		return result;
	}

	if(left_bytes > 0) {
		my_free_list = free_list + __freelist_index(left_bytes);
		((obj*)start_free)->free_list_link = *my_free_list;
		*my_free_list = (obj*)start_free;
	}
	
	bytes_to_get = 2*total_bytes + __round_up(heap_size >> 4);
	
	start_free = (char*)malloc(bytes_to_get);
	g_addr[g_addr_num ++] = start_free;

	if(start_free) {
		heap_size += bytes_to_get;
		end_free = start_free + bytes_to_get;
		return chunk_alloc(size,nobjs);
	}

	i = (int)__freelist_index(size) + 1;
	for(;i<__NFREELISTS;++i) {
		my_free_list = free_list + i;
		p = *my_free_list;
		if(p) {
			*my_free_list = p->free_list_link;
			start_free = (char*)p;
			end_free = start_free+(i + 1) * __ALIGN;
			return chunk_alloc(size,nobjs);
		}
	}
	
	end_free = NULL;//应该抛出异常
	return NULL;
}

static void mem_init() {
	int i;
	start_free = end_free = NULL;
	heap_size = 0;
	for(i=0;i<__NFREELISTS;free_list[i]=NULL,++i);
	memset(g_addr,0,sizeof(g_addr));
	g_addr_num = 0;
}

static void mem_destroy() {
	int i;
	for( i=0;i<g_addr_num;++i) {
		free(g_addr[i]);
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值