| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 941 人关注过本帖
标题:关于c进阶学籍里的代码不解(高分求)
只看楼主 加入收藏
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
结帖率:95.74%
收藏
已结贴  问题点数:100 回复次数:18 
关于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 编辑 ]
搜索更多相关主题的帖子: 还是 
2011-09-13 22:37
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
收藏
得分:0 
蛋疼啊,主要稍微解析一下。。
我自己懂了一些了

用心做一件事情就这么简单
2011-09-14 11:29
dreamofgod
Rank: 5Rank: 5
等 级:职业侠客
帖 子:194
专家分:341
注 册:2011-8-16
收藏
得分:11 
嗯,这种高难度问题,一定要顶上去。

一个单片机就让我头疼不已~~~
2011-09-14 12:08
dreamofgod
Rank: 5Rank: 5
等 级:职业侠客
帖 子:194
专家分:341
注 册:2011-8-16
收藏
得分:0 
我又来顶了。
收到的鲜花
  • 小鱼儿c2011-09-15 22:50 送鲜花  2朵   附言:这么好的孩子。。一定要奖励啊

一个单片机就让我头疼不已~~~
2011-09-15 10:52
其实、不想说
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:122
专家分:156
注 册:2011-3-3
收藏
得分:11 
dingba
2011-09-15 11:58
潇湘741
Rank: 2
等 级:论坛游民
帖 子:13
专家分:20
注 册:2011-9-4
收藏
得分:11 
,帮顶。
2011-09-15 14:13
fragileeye
Rank: 5Rank: 5
等 级:职业侠客
威 望:2
帖 子:107
专家分:387
注 册:2011-5-21
收藏
得分:11 
想知道这是哪本书里的?求分享。。。:(代码有点长,没时间看啊、
2011-09-15 14:29
dreamofgod
Rank: 5Rank: 5
等 级:职业侠客
帖 子:194
专家分:341
注 册:2011-8-16
收藏
得分:0 
一边看一边搜,无意中发现了。
楼主的代码是动态内存分配算法。
认真看了一遍,个人觉得与其听别人解释,不如去琢磨原文。

[ 本帖最后由 dreamofgod 于 2011-9-15 14:53 编辑 ]

一个单片机就让我头疼不已~~~
2011-09-15 14:48
laoyang103
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:内蒙古包头
等 级:贵宾
威 望:19
帖 子:3082
专家分:11056
注 册:2010-5-22
收藏
得分:11 
这么深究语法  我真的不行
收到的鲜花
  • 小鱼儿c2011-09-15 22:53 送鲜花  2朵   附言:给洋洋加分 不深究呢。。。。

                                         
===========深入<----------------->浅出============
2011-09-15 15:12
dreamofgod
Rank: 5Rank: 5
等 级:职业侠客
帖 子:194
专家分:341
注 册:2011-8-16
收藏
得分:0 
这种高深的东西了……看不下去

一个单片机就让我头疼不已~~~
2011-09-15 16:15
快速回复:关于c进阶学籍里的代码不解(高分求)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.047973 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved