您的位置:首页 > 其它

使用多链表实现malloc

2009-07-26 16:13 190 查看
//本人实在太懒了,没写一行注释,哈哈,没时间写,只是一个课堂练习

/////////////////////////////////////////////////////////////////////////////////////

//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;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: