使用多链表实现malloc

本文介绍了一个简单的自定义内存分配器的实现方法,包括内存分配与释放的流程,并通过一系列测试验证其性能表现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

//本人实在太懒了,没写一行注释,哈哈,没时间写,只是一个课堂练习

/

//makefile文件


OBJS=mainApp.o mini_malloc.o
malloc : mainApp.o mini_malloc.o
    gcc -g -o malloc ${OBJS}
mainApp.o : mainApp.c mini_malloc.h
    gcc -c -g mainApp.c
mini_malloc.o : mini_malloc.c mini_malloc.h
    gcc -c -g mini_malloc.c



/

//mini_malloc.h头文件


#include <stdio.h>
#include <stdlib.h>

#define MAXMEM 100000
#define NODESIZE (sizeof(Node))

typedef unsigned int size_t;

typedef struct Node {
    char _used;
    struct Node *_prev;
    struct Node *_next;
    struct Node *_usedprev;
    struct Node *_usednext;
    struct Node *_freeprev;
    struct Node *_freenext;
} Node;
extern Node *L;
extern char *P;

void *mini_malloc(size_t size);
void mini_free(void *addr);




/

//mainApp.c测试malloc性能,相当棒的一段测试代码,老师写的,我是看不懂了


#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include "mini_malloc.h"
 
#define MAXSIZE 0x1000
#define REPEAT 100
#define MEMPOOL 10000
 
#define DISPLAYMEM
 
typedef struct UnitTestNode {
    size_t _size;
    void* _ptr;
    struct UnitTestNode* _next;
} UnitTestNode;
 
static UnitTestNode* head = NULL;
static UnitTestNode* tail = NULL;
 
static int mem = 0;
static int max_mem = 0;
static int count_succeed = 0;
static int count_failed = 0;
static int count_free = 0;
static double time_succeed = 0.0;
static double time_failed = 0.0;
static double time_free = 0.0;
 
int insert(size_t size) {
    clock_t start, finish;
    void* ptr = NULL;
 
    start = clock();
    ptr = mini_malloc(size);
    finish = clock();
 
    if (ptr == NULL) {
        ++count_failed;
        time_failed += (double)(finish - start) * 1000 / CLOCKS_PER_SEC;
        return 0;
    }
 
    ++count_succeed;
    time_succeed += (double)(finish - start) * 1000 / CLOCKS_PER_SEC;
    mem += size;
    if (mem > max_mem) {
        max_mem = mem;
    }
 
    memset(ptr, 0xff, size);
 
    if (tail != NULL) {
        tail->_next = (UnitTestNode*)malloc(sizeof(UnitTestNode));
        tail = tail->_next;
    } else {
        tail = (UnitTestNode*)malloc(sizeof(UnitTestNode));
        head = tail;
    }
    tail->_size = size;
    tail->_ptr = ptr;
    tail->_next = NULL;
    return 1;
}
 
void delete(void) {
    clock_t start, finish;
    UnitTestNode* pNode = NULL;
 
    if(head != NULL) {
        pNode = head;
        head = head->_next;
        if (head == NULL) {
            tail = NULL;
        }
 
        start = clock();
        mini_free(pNode->_ptr);
        finish = clock();
 
        ++count_free;
        time_free += (double)(finish - start) * 1000 / CLOCKS_PER_SEC;
        mem -= pNode->_size;
 
        free(pNode);
    }
}
 
int blank(size_t size) {
    UnitTestNode* pNode = NULL;
    insert(size);
    pNode = tail;
    if (insert(size)) {
        tail->_next = head;
        head = tail;
        tail = pNode;
        tail->_next = NULL;
        return 1;
    } else {
        return 0;
    }
}
 
void print(int mark) {
#ifdef DISPLAYMEM
    int i, line_max, line_step;
    line_max = MEMPOOL;
    line_step = 150;
    printf("#%d |", mark);
    for (i = 0; i < line_max; i += line_step) {
        if (mem < line_max) {
            if (i < mem) {
                printf(".");
            } else {
                printf(" ");
            }
        } else {
            if (i + line_max < mem) {
                printf(":");
            } else {
                printf(".");
            }
        }
    }
    printf("|/n");
#endif
}
 
int main(int argc, char ** argv) {
    int i, n;
    srand(time(NULL));
 
    // Test 0
    for (i = 0; i < REPEAT * 10; ++i) {
        insert(sizeof(UnitTestNode));
        if (i % REPEAT == 0) {
            print(0);
        }
    }
 
    for (i = 0; i < REPEAT * 10; ++i) {
        delete();
        if (i % REPEAT == 0) {
            print(0);
        }
    }
 
    // Test 1
    for (n = MAXSIZE; n > 0; n >>= 1) {
        for (i = 0; i < REPEAT; ++i) {
            if (rand() % 2) {
                delete();
            }
            insert(n);
        }
        print(1);
    }
 
    for (n = 1; n <= MAXSIZE; n <<= 1) {
        for (i = 0; i < REPEAT; ++i) {
            if (rand() % 2) {
                delete();
            }
            insert(n);
        }
        print(1);
    }
 
    // Test 2
    for (n = 1; n <= MAXSIZE; n <<= 1) {
        for (i = 0; i < REPEAT; ++i) {
            if (rand() % 2) {
                delete();
            }
            insert((rand() % n) + 1);
        }
        print(2);
    }
 
    while (head != NULL) {
        delete();
    }
    print(2);
 
    for (n = 1; n <= MAXSIZE; n <<= 1) {
        for (i = 0; i < REPEAT; ++i) {
            if (rand() % 2) {
                delete();
            }
            insert((rand() % n) + 1);
        }
        print(2);
    }
 
    // Test 3
    for (i = 0; i <= REPEAT * 10; ++i) {
        if (rand() % 2) {
            delete();
        }
        insert((rand() % REPEAT) + 1);
        if (i % REPEAT == 0) {
            print(3);
        }
    }
 
    while (head != NULL) {
        delete();
    }
    print(3);
 
    for (i = 0; i <= REPEAT * 10; ++i) {
        if (rand() % 2) {
            delete();
        }
        insert((rand() % REPEAT) + 1);
        if (i % REPEAT == 0) {
            print(3);
        }
    }
 
    // Test 4
    while (head != NULL) {
        delete();
    }
    print(4);
 
    for (i = 0; i < MEMPOOL; ++i) {
        if (blank(1) == 0) {
            break;
        }
        if (i % (MEMPOOL / 12) == 0) {
            print(4);
        }
    }
 
    while(--i) {
        delete();
    }
    print(4);
 
    for (i = 0; i < REPEAT * 10; ++i) {
        insert(MEMPOOL / 2);
        if (i % REPEAT == 0) {
            print(4);
        }
    }
 
    // Test 5
    for (i = 0; i <= REPEAT * 10; ++i) {
        if (rand() % 4) {
            delete();
        }
        insert(sizeof(UnitTestNode));
        if (i % 60 == 0) {
            print(5);
        }
    }
 
    while (head != NULL) {
        delete();
    }
    print(5);
 
    for (i = 0; i <= MEMPOOL; ++i) {
        insert(sizeof(char));
        if (i % 600 == 0) {
            print(5);
        }
    }
 
    printf("%d times succeed malloc", count_succeed);
    if (count_succeed != 0) {
        printf(", which average costs %.3f ms./n", time_succeed / count_succeed);
    } else {
        printf("./n");
    }
 
    printf("%d times failed malloc", count_failed);
    if (count_failed != 0) {
        printf(", which average costs %.3f ms./n", time_failed / count_failed);
    } else {
        printf("./n");
    }
 
    printf("%d times free", count_free);
    if (count_free != 0) {
        printf(", which average costs %.3f ms./n", time_free / count_free);
    } else {
        printf("./n");
    }
 
    printf("%d memories used, %d memories used at the peak./n", mem, max_mem);
 
    return 0;
}



/

//mini_malloc内存分配与释放


#include "mini_malloc.h"

extern char *P = '/0';
extern Node *L = NULL;

Node *uNode = NULL;
Node *fNode = NULL;

void DLpushfront(Node *pNode, char obj);
void DLdelete(Node **head, char obj);

void init_malloc()
{
    P = (char *)malloc(MAXMEM);
    L = (Node *)P;
    L->_used = '/0';
    L->_prev = NULL;
    L->_next = NULL;
    L->_usedprev = NULL;
    L->_usednext = NULL;
    L->_freeprev = NULL;
    L->_freenext = NULL;
    fNode = L;
}

void *mini_malloc(size_t size)
{
    if (L == NULL)
        init_malloc();
    size_t fsize = 0;
    Node *head = fNode;
    while (head) {
        if (head->_used == '/0') {
            if (head->_next != NULL) {
                fsize = (char *)(head->_next) - (char *)head - NODESIZE;
            }
            else {
                fsize = P + MAXMEM - (char *)head - NODESIZE;
            }
            if (fsize >= size) {
                head->_used = '1';
                DLpushfront(head, 'u');
                DLdelete(&head, 'f');
                if (fsize - size > NODESIZE) {
                    Node *node = (Node *)((char *)head + NODESIZE + size);
                    node->_used = '/0';
                    node->_prev = head;
                    node->_next = NULL;
                    node->_freenext = NULL;
                    if (head->_next != NULL) {
                        node->_next = head->_next;
                        head->_next->_prev = node;
                    }
                    DLpushfront(node, 'f');
                    head->_next = node;
                }
                return (void *)((char *)head + NODESIZE);
            }
        }
        head = head->_freenext;
    }
}

void mini_free(void *addr)
{
    if (uNode == NULL)
        return;
    Node *Used = uNode;
    Node *node = NULL;
    while (Used) {
        if ((Node *)((char *)addr - NODESIZE) == Used) {
            Used->_used = '/0';
            node = Used;
            DLdelete(&Used, 'u');
            if (Used->_next != NULL && Used->_next->_used == '/0') {
                DLdelete(&(Used->_next), 'f');
                DLdelete(&(Used->_next), 'm');
            }
            if (Used->_prev != NULL && Used->_prev->_used == '/0') {
                node = Used->_prev;
                DLdelete(&node, 'f');
                DLdelete(&Used, 'm');
            }
            DLpushfront(node, 'f');
            return;
        }
        Used = Used->_usednext;
    }
}

void DLpushfront(Node *pNode, char obj)
{
    if (pNode == NULL) return;
    switch (obj) {
    case 'm':
        if (L == NULL) {
            L = pNode;
            L->_prev = NULL;
            L->_next = NULL;
        }
        else {
            pNode->_next = L;
            L->_prev = pNode;
            L = pNode;
            L->_prev = NULL;
        }
        break;
    case 'u':
        if (uNode == NULL) {
            uNode = pNode;
            uNode->_usedprev = NULL;
            uNode->_usednext = NULL;
        }
        else {
            pNode->_usednext = uNode;
            uNode->_usedprev = pNode;
            uNode = pNode;
            uNode->_usedprev = NULL;
        }
        break;
    case 'f':
        if (fNode == NULL) {
            fNode = pNode;
            fNode->_freeprev = NULL;
            fNode->_freenext = NULL;
        }
        else {
            pNode->_freenext = fNode;
            fNode->_freeprev = pNode;
            fNode = pNode;
            fNode->_freeprev = NULL;
        }
        break;
    }
}

void DLdelete(Node **head, char obj)
{
    if (*head == NULL) return;
    Node *T = *head;
    switch (obj) {
    case 'm':
        if (T->_prev != NULL) {
            if (T->_next != NULL) {
                T->_prev->_next = T->_next;
                T->_next->_prev = T->_prev;
            }
            else
                T->_prev->_next = NULL;
        }
        else {
            printf("ERROR/n");
        }
        break;
    case 'u':
        if (T->_usedprev != NULL) {
            if (T->_usednext != NULL) {
                T->_usedprev->_usednext = T->_usednext;
                T->_usednext->_usedprev = T->_usedprev;
            }
            else
                T->_usedprev->_usednext = NULL;
        }
        else {
            if (T->_usednext != NULL) {
                uNode = T->_usednext;
                uNode->_usedprev = NULL;
            }
            else
                uNode = NULL;
        }
        break;
    case 'f':
        if (T->_freeprev != NULL) {
            if (T->_freenext != NULL) {
                T->_freeprev->_freenext = T->_freenext;
                T->_freenext->_freeprev = T->_freeprev;
            }
            else
                T->_freeprev->_freenext = NULL;
        }
        else {
            if (T->_freenext != NULL) {
                fNode = T->_freenext;
                fNode->_freeprev = NULL;
            }
            else
                fNode = NULL;
        }
        break;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值