关于c进阶学籍里的代码不解(高分求)
他貌似没有说思路给了几张图我看许久我还是没有看明白,
给我说思路。
那个三个全局指针 每个指针的含义 。。谢谢了
于是我在论坛求救了
test.c
程序代码:#include <stdio.h>
#include "xlmalloc.h"
main()
{
char *p, *q,*t;
p = (char *)SysLmalloc(2);
q = (char *)SysLmalloc(16);
t = (char *)SysLmalloc(24);
SysLfree(q);
SysLfree(t);
t = (char *)SysLmalloc(16);
printf("this is a test string\n");
return 0;
}
Lmalloc.c
程序代码:#include <stdlib.h>
#include <string.h>
#include "xlmalloc.h"
static unsigned long Memfail=0L; /* Count of allocation failures */
static unsigned long Allocs=0L; /* Total allocations */
static unsigned long Frees=0L; /* Total frees */
static unsigned long Invalid=0L; /* Total calls to SysLfree with garbage arg(自变量) */
/* The array is to record the number that
* the special sized memory block(块) is used.
* Sizes[0] ----- memory block size: 2/0
* .....
* Sizes[n] ----- memory block size: 2/n
* max block size is 2/19 = 128K */
static unsigned long Sizes[20]={ 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 0L, 0L };
/* This debugging pattern MUST be exactly equal in size
* to the "header" union defined later */
static char Debugpat[] = { 0xfe,0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef };
static HEADER *Base=NULL; //堆的基地址指针
static HEADER *First=NULL; //第一个有效的分配块
static HEADER *Allocp = NULL; //FreeList的首指针
struct sheader heap[Heapsize/sizeof(struct sheader)];
//char array_memory[Heapsize];
/* Heap memory, ABLKSIZE units */
static unsigned long Availmem = BTOU(Heapsize)-2;
#ifdef HOT_RESET_DEBUG_CODE_ENABLE //如果系统支持热复位,需要我们手工将所有的全局变量重新置初值
void SysLmallocInit(void)
{
int i;
#if ENABLE_SYSMEM_DEBUG_OUT
MemUsed = 0L;
MemUsedPeak = 0L;
#endif
Memfail = 0L;
Allocs = 0L;
Frees = 0L;
Invalid = 0L;
for(i=0; i<20; i++)
Sizes[i] = 0L;
Base = NULL;
First = NULL;
Allocp = NULL;
Availmem = BTOU(Heapsize)-2;
}
#endif
static char ilog2(int size)
{
char i;
int mask = 0x80000000;
for( i = 0; i < 16; i++ )
{
if( size & mask )
break;
else
mask = mask >> 1;
}
return ( 16 - i );
}
/* Allocate block of 'nb' bytes */
void *SysLmalloc( int nb )
{
#if Memdebug
int i;
#endif
register HEADER *p, *q;
register unsigned long nu;
if(nb == 0)
return NULL;
Allocs++;
#if Memdebug
/* Record the size of this request */
if((i = ilog2(nb)) >= 0)
Sizes[i]++;
#endif
/* Round up to full block, then add one for header */
nu = BTOU(nb);
//注意:我们在这里进入临界区,我们将调用OS提供的API关闭任务调度
//vDisableDispatch();
/* Initialize heap pointers if necessary */
if((q = Allocp) == NULL){
//创建一个空头。目的:当所有空间分配完时,Lfree函数需要有一个表头
Base = (HEADER *)heap; //array_memory;
Base->s.ptr = Allocp = q = Base;
Base->s.size = 1;
First = Base + 1;
Base->s.ptr = First;
First->s.ptr = Base;
First->s.size = BTOU(Heapsize)-2; //注意BTOU要加一,所以这里要减二(BASE用了一块)
}
/* Search heap list */
for(p = q->s.ptr; ; q = p, p = p->s.ptr){
if(p->s.size >= nu){
/* This chunk(大块) is at least as large as we need */
if(p->s.size <= nu + 1){
/* This is either a perfect fit (size == nu)
* or the SysLfree chunk is just one unit larger.
* In either case, alloc the whole thing,
* because there's no point in keeping a SysLfree
* block only large enough to hold the header.
*/
q->s.ptr = p->s.ptr;
} else {
/* Carve out piece from end of entry */
p->s.size -= nu;
p += p->s.size;
p->s.size = nu;
}
p->s.ptr = p; /* for auditing */
Availmem -= p->s.size;
p++;
#if Memdebug
// debug for memory test
memset( p, 0xcc, nb );
#endif
break;
}
/* We've searched all the way around the list without
* finding anything. 我们将返回空指针,内存分配失败!
*/
if(p == Allocp){
p = NULL;
Memfail++;
break;
}
}
//注意:出临界区,重新打开内核的调度
//vEnableDispatch();
return (void *)p;
}
/* Put memory block back on heap(堆) */
void SysLfree( void *blk )
{
register HEADER *p, *q;
unsigned int i;
if(blk == NULL)
return; /* Required by ANSI */
Frees++;
p = ((HEADER *)blk) - 1; //p 指向该内存块的头部
/* Audit check,检查该块内存是否是合法分配的 */
if(p->s.ptr != p){
Invalid++;
return;
}
Availmem += p->s.size;
#if Memdebug
/* Fill data area with pattern to detect later overwrites */
for(i=1;i<p->s.size;i++)
memcpy(p[i].c,Debugpat,sizeof(Debugpat));
#endif
//注意:我们在这里进入临界区,我们将调用OS提供的API关闭任务调度
//vDisableDispatch();
/* Search the SysLfree list looking for the right place to insert */
//从Allocp FreeList的头部开始搜索
for(q = Allocp; !(p > q && p < q->s.ptr); q = q->s.ptr){
/* Highest address on circular list? */
if(q >= q->s.ptr && (p > q || p < q->s.ptr))
break;
}
if(p + p->s.size == q->s.ptr){
/* Combine with front of this entry */
//与下一个Free块的头部合并
p->s.size += q->s.ptr->s.size;
p->s.ptr = q->s.ptr->s.ptr;
#if Memdebug
memcpy(q->s.ptr->c,Debugpat,sizeof(Debugpat));
#endif
} else {
/* Link to front of this entry */
//将P块加入到FreeList(p块的next指针指向下一块)
p->s.ptr = q->s.ptr;
}
//看看P块是否可能与前一个Free块(q块)的尾部合并?当然如果q块是BASE的话,我们就不合并
if((q + q->s.size == p) && (q != Base)){
/* Combine with end of this entry */
q->s.size += p->s.size;
q->s.ptr = p->s.ptr;
#if Memdebug
memcpy(p->c,Debugpat,sizeof(Debugpat));
#endif
} else {
/* Link to end of this entry */
//将P块加入到FreeList(q块的next指针指向p)
q->s.ptr = p;
}
//注意:出临界区,重新打开内核的调度
//vEnableDispatch();
return;
}
/* Move existing block to new area */
void *SysLrealloc( void *area, int size )
{
unsigned osize;
HEADER *hp;
void *pnew;
if(size == 0)
return NULL;
hp = ((HEADER *)area) - 1;
if(hp->s.ptr != hp)
return NULL;
osize = (hp->s.size -1) * ABLKSIZE;
/* We must copy the block since freeing it may cause the heap
* debugging code to scribble over it.
*/
if((pnew = SysLmalloc(size)) != NULL)
memcpy(pnew,area,size>osize? osize : size);
SysLfree(area);
return pnew;
}
/* Allocate block of cleared memory */
void *SysLcalloc( int size )
{
register char *cp;
if(size == 0)
return NULL;
if((cp = SysLmalloc(size)) != NULL)
memset(cp,0,size);
return cp;
}
/* Version of SysLmalloc() that waits if necessary for memory to become available */
/*
void *
SysLmallocw(nb)
WORD nb;
{
register void *p;
if(nb == 0)
return NULL;
while((p = SysLmalloc(nb)) == NULL){
Memwait++;
twai_sem(Memsem, TMO_FEVR);
Memwait--;
}
return p;
}
*/
/* Version of calloc that waits if necessary for memory to become available */
/*
void *
Lcallocw(size)
unsigned size; // Size of each element
{
register char *cp;
if(size == 0)
return NULL;
cp = SysLmallocw(size);
memset(cp,0,size);
return cp;
}
*/
/* Print heap stats : only for debug */
/*
int
dostat(void)
{
int i;
printf("heap size %lu avail %lu (%lu%%) \n",
Heapsize,Availmem * ABLKSIZE,100L*Availmem*ABLKSIZE/Heapsize);
printf("allocs %lu frees %lu (diff %lu) alloc fails %lu invalid frees %lu\n",
Allocs,Frees,Allocs-Frees,Memfail,Invalid);
printf("\n");
return 0;
}
*/
/* Print heap Lfree list */
/*
int
dofreelist(void)
{
HEADER *p;
int i = 0;
int j;
unsigned corrupt;
int i_state;
for(p = Base->s.ptr;p != (HEADER *)Base;p = p->s.ptr){
corrupt = 0;
if(Memdebug){
//i_state = dirps();
for(j=1;j<p->s.size;j++){
if(memcmp(p[j].c,Debugpat,sizeof(Debugpat)) != 0){
corrupt = j;
break;
}
}
//restore(i_state);
}
if(corrupt)
printf("%p %6lu C: %u",p,(p->s.size - 1) * ABLKSIZE,corrupt);
else
printf("%p %6lu",p,(p->s.size - 1) * ABLKSIZE);
if(++i == 4){
i = 0;
if(printf("\n") == EOF)
return 0;
} else
printf(" | ");
}
if(i != 0)
printf("\n");
return 0;
}
int
dosizes(void)
{
int i;
for(i=0;i<16;i += 4){
printf("N>=%5u:%7ld| N>=%5u:%7ld| N>=%5u:%7ld| N>=%5u:%7ld\n",
1<<i,Sizes[i], 2<<i,Sizes[i+1],
4<<i,Sizes[i+2],8<<i,Sizes[i+3]);
}
return 0;
}
*/
xlmalloc.h
程序代码:#ifndef XLMALLOC_H
#define XLMALLOC_H
union header {
struct {
union header *ptr;
unsigned long size;//本块大小
} s;
char c[8]; // For debugging; also ensure size is 8 bytes
};
// sheader结构是header结构的变形,主要是为了方便大家调试时观测
struct sheader {
struct sheader *ptr;
unsigned long size;
};
typedef union header HEADER;
#define ABLKSIZE (sizeof (HEADER)) //一个分配块的大小,这里是8个字节
//将用户的分配字节数换算成为分配块的个数,注意:加一是为这个分配块留一个头部
#define BTOU(nb) ((((nb) + ABLKSIZE - 1) / ABLKSIZE) + 1)
#define Heapsize (10*8) //为了让大家方便调试,我们只给出了一个非常小的堆空间,且是分配块大小(8字节)的整数倍
#define Memdebug 1 //打开调试宏
//函数原型声明
extern void *SysLmalloc( int nb );
extern void SysLfree( void *blk );
#endif
[ 本帖最后由 小鱼儿c 于 2011-9-13 23:49 编辑 ]










dingba
,帮顶。
……看不下去