-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgalloc.c
174 lines (141 loc) · 2.8 KB
/
galloc.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/*
* Course IFJ @ FIT VUT Brno, 2015
* IFJ15 Interpreter Project
*
* Authors:
* Lukas Osadsky - xosads00
* Pavol Plaskon - xplask00
* Pavel Pospisil - xpospi88
* Matej Postolka - xposto02
*
* Unless otherwise stated, all code is licensed under a
* GNU General Public License v2.0
*
*/
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include "galloc.h"
#include "error.h"
#define INITIAL_SIZE 1000
#define AUTORESIZE_COEF 2
typedef struct Vector
{
void **data;
int capacity;
int used;
bool initialized;
} TVector;
// Forward declarations of private functions
int initVector();
int resizeVector();
int insertIntoVector();
void deleteFromVector();
void freeVector();
// This is global so it can be safely initialized
TVector mem;
int initVector(TVector *v, int size)
{
v->data = malloc(size * sizeof(void*));
if (v->data == NULL)
exit_error(E_ALLOC);
v->capacity = size;
v->used = 0;
return E_OK;
}
int resizeVector(TVector *v, int size)
{
// Cannot shrink used data
assert(size > v->used);
void *newData;
// Prevent memory leak by using a temporary pointer
newData = realloc(v->data, size * sizeof(void*));
if (newData == NULL)
exit_error(E_ALLOC);
v->data = newData;
v->capacity = size;
return E_OK;
}
int insertIntoVector(TVector *v, void *value)
{
// Vector is full, automatically extend
int ret = E_OK;
if (v->used >= v->capacity)
ret = resizeVector(v, v->capacity * AUTORESIZE_COEF);
if (ret != E_OK)
return ret;
// v->used will be the same as the first free index
v->data[v->used] = value;
(v->used)++;
return E_OK;
}
void deleteFromVector(TVector *v, int index)
{
assert(index >= 0 && index < v->used);
// Remove value by replacing it with NULL
v->data[index] = NULL;
}
void freeVector(TVector *v)
{
free(v->data);
}
void searchAndRemove(TVector *v, void *value)
{
// If address is matched, remove it from vector
for (int i=0; i < v->used; i++)
{
if (value == v->data[i])
{
deleteFromVector(v, i);
break;
}
}
}
int gcInit()
{
if (initVector(&mem, INITIAL_SIZE) != E_OK)
exit_error(E_ALLOC);
mem.initialized = true;
return E_OK;
}
void gcDestroy()
{
if (mem.initialized == false)
return;
for (int i=0; i<mem.used; i++)
{
free(mem.data[i]);
}
free(mem.data);
mem.initialized = false;
}
void *gmalloc(int size)
{
// assert(mem.initialized);
void *ptr;
ptr = malloc(size);
if (ptr == NULL)
exit_error(E_ALLOC);
// insertIntoVector(&mem, ptr);
return ptr;
}
void *grealloc(void *ptr, int size)
{
//assert(mem.initialized);
void *newPtr;
newPtr = realloc(ptr, size);
if (newPtr == NULL)
exit_error(E_ALLOC);
/* if (newPtr != ptr)
{
searchAndRemove(&mem, ptr);
insertIntoVector(&mem, newPtr);
}
*/
return newPtr;
}
void gfree(void *ptr)
{
// searchAndRemove(&mem, ptr);
free(ptr);
}