-
Notifications
You must be signed in to change notification settings - Fork 0
/
dynarray.c
171 lines (119 loc) · 3.1 KB
/
dynarray.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
/*
* This file contains the definitions of structures and functions implementing
* a dynamic array.
*/
#include <stdlib.h>
#include <assert.h>
#include "dynarray.h"
#define DYNARRAY_INIT_CAPACITY 8
/*
* This is the definition of the dynamic array structure. Note that because
* we're storing generic pointers as void*, the data array needs to be an
* array of void*, hence it is of type void**.
*/
struct dynarray {
void** data;
int size;
int capacity;
};
struct dynarray* dynarray_create() {
struct dynarray* da = malloc(sizeof(struct dynarray));
assert(da);
da->data = malloc(DYNARRAY_INIT_CAPACITY * sizeof(void*));
assert(da->data);
da->size = 0;
da->capacity = DYNARRAY_INIT_CAPACITY;
return da;
}
void dynarray_free(struct dynarray* da) {
assert(da);
free(da->data);
free(da);
}
int dynarray_size(struct dynarray* da) {
assert(da);
return da->size;
}
/*
* Auxilliary function to perform a resize on the underlying array.
*/
void _dynarray_resize(struct dynarray* da, int new_capacity) {
assert(new_capacity > da->size);
/*
* Allocate space for the new array.
*/
void** new_data = malloc(new_capacity * sizeof(void*));
assert(new_data);
/*
* Copy data from the old array to the new one.
*/
for (int i = 0; i < da->size; i++) {
new_data[i] = da->data[i];
}
/*
* Put the new array into the dynarray struct.
*/
free(da->data);
da->data = new_data;
da->capacity = new_capacity;
}
void dynarray_insert(struct dynarray* da, int idx, void* val) {
assert(da);
assert((idx <= da->size && idx >= 0) || idx == -1);
// Let users specify idx = -1 to indicate the end of the array.
if (idx == -1) {
idx = da->size;
}
/*
* Make sure we have enough space for the new element.
*/
if (da->size == da->capacity) {
_dynarray_resize(da, 2 * da->capacity);
}
/*
* Move all elements behind the new one back one index to make space
* for the new one.
*/
for (int i = da->size; i > idx; i--) {
da->data[i] = da->data[i-1];
}
/*
* Put the new element into the array.
*/
da->data[idx] = val;
da->size++;
}
void dynarray_remove(struct dynarray* da, int idx) {
assert(da);
assert((idx < da->size && idx >= 0) || idx == -1);
// Let users specify idx = -1 to indicate the end of the array.
if (idx == -1) {
idx = da->size - 1;
}
/*
* Move all elements behind the one being removed forward one index,
* overwriting the element to be removed in the process.
*/
for (int i = idx; i < da->size - 1; i++) {
da->data[i] = da->data[i+1];
}
da->size--;
}
void* dynarray_get(struct dynarray* da, int idx) {
assert(da);
assert((idx < da->size && idx >= 0) || idx == -1);
// Let users specify idx = -1 to indicate the end of the array.
if (idx == -1) {
idx = da->size - 1;
}
return da->data[idx];
}
void dynarray_set(struct dynarray* da, int idx, void* val) {
assert(da);
assert((idx < da->size && idx >= 0) || idx == -1);
// Let users specify idx = -1 to indicate the end of the array.
if (idx == -1) {
idx = da->size - 1;
}
da->data[idx] = val;
}