-
Notifications
You must be signed in to change notification settings - Fork 0
/
memchk.c
139 lines (125 loc) · 3.16 KB
/
memchk.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include <stdlib.h>
#include <stddef.h>
#include <assert.h>
#include <memory.h>
#include <stack>
#include "except.h"
#include "mem.h"
using namespace std;
#define NDESCRIPTORS 512
#define hash(p,t) (((unsigned long)(p)>>3) & (sizeof (t)/sizeof ((t)[0])-1)) //?
#define NALLOC ((4096 + sizeof (union align) -1) / (sizeof(union align))) * (sizeof(union align))
const Except_T Assert_Failed = {"Assert Failed"};
const Except_T Mem_Failed = {"Allocation Failed"};
union align
{
int i;
long l;
long *lp;
void *p;
void (*fp)(void);
float f;
double d;
long double ld;
};
static struct descriptor
{
struct descriptor *free;
struct descriptor *link;
const void *ptr;
long size;
const char *file;
int line;
} *htab[2048];
static struct descriptor freelist = {&freelist};
static struct descriptor *find(const void *ptr){
struct descriptor *bp = htab[hash(ptr,htab)];
while (bp && bp->ptr != ptr)
bp = bp->link;
return bp;
}
void Mem_free(void *ptr, const char *file, int line){
if(ptr){
struct descriptor *bp;
if(((unsigned long)ptr)%(sizeof (union align))!=0 || (bp = find(ptr)) == NULL || bp->free)
Except_raise(&Assert_Failed,file,line);
bp->free = freelist.free;
freelist.free=bp;
}
}
void *Mem_resize(void *ptr, long nbytes, const char *file, int line){
struct descriptor *bp;
void *newptr;
assert(ptr);
assert(nbytes > 0);
if(((unsigned long)ptr)%(sizeof (union align))!=0 || (bp = find(ptr)) == NULL || bp->free)
Except_raise(&Assert_Failed,file,line);
newptr = Mem_alloc(nbytes,file,line);
memcpy(newptr,ptr,nbytes < bp->size ? nbytes : bp->size);
Mem_free(ptr,file,line);
return newptr;
}
void *Mem_calloc(long count, long nbytes , const char *file, int line){
void *ptr;
assert(count > 0);
assert(nbytes > 0);
ptr = Mem_alloc(count*nbytes,file,line);
memset(ptr,'\0',count*nbytes);
return ptr;
}
static struct descriptor *dalloc(void *ptr, long size, const char *file ,int line)
{
static struct descriptor *avail;
static int nleft;
if(nleft <= 0)
{
avail = (descriptor *)malloc(NDESCRIPTORS*sizeof (*avail));
if(avail == NULL)
return NULL;
nleft = NDESCRIPTORS;
}
avail->ptr = ptr;
avail->size = size;
avail->file = file;
avail->line = line;
avail->free = avail->link = NULL;
nleft--;
return avail++;
}
void *Mem_alloc(long nbytes, const char *file, int line){
struct descriptor *bp;
void *ptr;
assert(nbytes > 0);
nbytes = ((nbytes + sizeof (union align) - 1) / (sizeof (union align))) * (sizeof (union align)); //¶ÔnbytesÏòÉÏÈ¡Õû
for(bp =freelist.free;bp;bp = bp->free){
if(bp->size > nbytes){
bp->size -= nbytes;
ptr = (char*)bp->ptr + bp->size;
if((bp = dalloc(ptr,nbytes,file,line)) != NULL){
unsigned h = hash(ptr,htab);
bp->link = htab[h];
htab[h] = bp;
return ptr;
}else {
if(file == NULL)
RAISE(Mem_Failed);
else
Except_raise(&Mem_Failed,file,line);
}
}
if(bp == &freelist){
struct descriptor *newptr;
if((ptr = malloc(nbytes+NALLOC)) == NULL || (newptr = dalloc(ptr,nbytes + NALLOC, __FILE__,__LINE__)) == NULL)
{
if(file == NULL)
RAISE(Mem_Failed);
else
Except_raise(&Mem_Failed,file,line);
}
}
}
stack<int> s;
s.empty();
assert(0);
return NULL;
}