关于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 编辑 ]