C - bfree(p,n) that will free any arbitrary block p of n characters into the free list

这篇博客通过一个简单的C语言实现,详细介绍了如何从零开始创建自己的内存管理系统,包括malloc、calloc、free和bfree等函数。作者通过实例展示了如何动态分配和释放内存,帮助读者深入理解内存管理原理。
摘要由CSDN通过智能技术生成

分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击人工智能教程

/*
 * Write a routine bfree(p,n) that will free any arbitrary block p of n characters
 * into the free list maintained by malloc and free. By using bfree, a user can add
 * a static or external array to the free list at any time.
 *
 * BFree.c - by FreeMan
 */

#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>

#define NALLOC 1024

typedef long Align;

union header
{
	struct
	{
		union header *ptr;
		unsigned size;
	} s;
	Align x;
};

typedef union header Header;

static Header base;
static Header *freep = NULL;

static void *_malloc(unsigned nbytes);
static void *_calloc(unsigned nbytes, unsigned size);
static Header *morecore(unsigned nu);
static void _free(void *ap);
static void bfree(void *p, unsigned n);

int main(void)
{
	char *c, *d, *f;;
	char e[1096];

	if ((c = (char *)_malloc(sizeof(char) * 1000)) == NULL
		|| (d = (char *)_calloc(sizeof(char), 1000)) == NULL)
	{
		fprintf(stderr, "malloc: returned NULL\n");
		exit(1);
	}
	strcpy(c, "hello,world");
	strcpy(d, "hello,ecorp");
	printf("==> %s\n", c);
	printf("==> %s\n", d);
	_free(c);
	_free(d);

	printf(" array is at @0x%p\n", e);
	bfree(e, 1096);
	if ((f = (char *)_calloc(sizeof(char), 1024)) == NULL)
	{
		fprintf(stderr, "malloc: returned NULL\n");
		exit(1);
	}
	printf("calloc is at @0x%p\n", f);
	strcpy(f, "hello,bobby");
	printf("==> %s\n", f);
	_free(f);

	return 0;
}

static void *_calloc(unsigned nbytes, unsigned size)
{
	void *p;
	unsigned t = nbytes * size;

	if ((p = _malloc(t)) == NULL)
	{
		return NULL;
	}
	memset(p, 0, t);
	return p;
}

static void *_malloc(unsigned nbytes)
{
	Header *p, *prevp;
	Header *morecore(unsigned);
	unsigned nunits;

	if (nbytes == 0 || nbytes >= UINT_MAX - NALLOC)
	{
		fprintf(stderr, "malloc: invalid size %u\n", nbytes);
		return NULL;
	}
	nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
	if ((prevp = freep) == NULL)
	{
		base.s.ptr = freep = prevp = &base;
		base.s.size = 0;
	}
	for (p = prevp->s.ptr; ; prevp = p, p = p->s.ptr)
	{
		if (p->s.size >= nunits)
		{
			if (p->s.size == nunits)
			{
				prevp->s.ptr = p->s.ptr;
			}
			else
			{
				p->s.size -= nunits;
				p += p->s.size;
				p->s.size = nunits;
			}
			freep = prevp;
			return (void *)(p + 1);
		}
		if (p == freep)
		{
			if ((p = morecore(nunits)) == NULL)
			{
				return NULL;
			}
		}
	}
}

static Header *morecore(unsigned nu)
{
	char *cp;
	Header *up;

	if (nu < NALLOC)
	{
		nu = NALLOC;
	}
	cp = sbrk(nu * sizeof(Header));
	if (cp == (char *)-1)
	{
		return NULL;
	}
	up = (Header *)cp;
	up->s.size = nu;
	_free((void *)(up + 1));
	return freep;
}

static void _free(void *ap)
{
	Header *bp, *p;

	bp = (Header *)ap - 1;
	if (bp->s.size == 0 || bp->s.size == UINT_MAX - NALLOC)
	{
		fprintf(stderr, "free: invalid block size %u\n", bp->s.size);
		return;
	}
	for (p = freep; !(bp > p && bp < p->s.ptr); p = p->s.ptr)
	{
		if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
		{
			break;
		}
	}
	if (bp + bp->s.size == p->s.ptr)
	{
		/* we should check for UINT_MAX overflow before merge */
		bp->s.size += p->s.ptr->s.size;
		bp->s.ptr = p->s.ptr->s.ptr;
	}
	else
	{
		bp->s.ptr = p->s.ptr;
	}
	if (p + p->s.size == bp)
	{
		/* we should check for UINT_MAX overflow before merge */
		p->s.size += bp->s.size;
		p->s.ptr = bp->s.ptr;
	}
	else
	{
		p->s.ptr = bp;
	}
	freep = p;
}

static void bfree(void *p, unsigned n)
{
	Header *bp;

	if (n < NALLOC)
	{
		fprintf(stderr, "bfree: block is to short, %u must be at least %u\n", n, NALLOC);
		return;
	}
	bp = (Header *)p;
	/* We must substract 1 sizeof(Header) to size for Header space */
	bp->s.size = (n / sizeof(Header)) - 1;
	_free((void *)(bp + 1));
}

// Output:
/*
$ ./a.out
==> hello,world
==> hello,ecorp
array is at @0x0x7ffc306ad910
calloc is at @0x0x7ffc306ad940
==> hello,bobby
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值