| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 941 人关注过本帖
标题:关于c进阶学籍里的代码不解(高分求)
取消只看楼主 加入收藏
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
结帖率:95.74%
收藏
已结贴  问题点数:100 回复次数:5 
关于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
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
收藏
得分:0 
回复 7楼 fragileeye
网速不可能力 就是c语言进阶
我在看类似的代码
在一本书里 我网速一起传好不好。
求分

用心做一件事情就这么简单
2011-09-15 22:51
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
收藏
得分:0 
我自己顶一下@@

用心做一件事情就这么简单
2011-09-16 23:41
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
收藏
得分:0 
那个为什么结构要用UNION啊

用心做一件事情就这么简单
2011-09-16 23:43
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
收藏
得分:0 
回复 18楼 dreamofgod
我也看了好多有关了,貌似这都是模拟。。
先申请一段静态模拟内存。
再根据内存分配的算法。
什么 最坏算法 最佳算法 最先算法 各有各的优势。
再。里面还要有写优化代码。。。。所以要写好这个模拟代码还是比较难。。
可能作者写的代码 我不太习惯他。
所以看起来就不舒服。我也没有写一下。
在c语言设计UNIX界面有类似代码 。
貌似不一样。他还用了一个函数向系统申请内存。。
不过我们也可以向系统申请连续的内存空间。。。。
非常感谢你。。。
鄙视那些高手不说,可能那高手不屑吧。。。但为什么有些小问题高手又回答。。。。
看来哥RP不好啊

用心做一件事情就这么简单
2011-09-18 14:27
快速回复:关于c进阶学籍里的代码不解(高分求)
数据加载中...
 
   



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

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