/[paths]/src/graph.c
ViewVC logotype

Contents of /src/graph.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 14 - (show annotations)
Sun Aug 12 10:21:50 2012 UTC (7 years, 2 months ago) by ben
File MIME type: text/plain
File size: 3783 byte(s)
fix mem leak
1 #include <string.h>
2 #include <stdlib.h>
3 #include <time.h>
4 #include <assert.h>
5 #include "graph.h"
6
7 void node_destroy(struct node* n)
8 {
9 int i;
10 for(i = 0; i < n->count; i++) {
11 node_unlink(n, n->neighbours[i].to);
12 }
13 free(n->neighbours);
14 n->neighbours = NULL;
15 return;
16 }
17
18 void node_randomize(struct node* n)
19 {
20 n->event.pitch = rand() % 128;
21 n->event.duration = rand();
22 n->event.attack = rand() % 128;
23 n->event.decay = rand() % 128;
24 n->event.sustain = rand() % 128;
25 n->event.release = rand() % 128;
26 n->event.instrument = rand() % 128;
27 n->event.modulation = rand() % 128;
28 n->event.detune = rand() % 128;
29 n->event.velocity = rand() % 128;
30 n->event.volume = rand() % 128;
31 }
32
33 void edge_randomize(struct edge* e)
34 {
35 e->distance = rand();
36 }
37
38 int node_is_linked(struct node* a, struct node* b)
39 {
40 int i;
41 for (i = 0; i < a->count; i++) {
42 if (a->neighbours[i].to == b)
43 return 1;
44 }
45 return 0;
46 }
47
48 int node_link(struct node* a, struct node* b, int distance)
49 {
50 struct edge *nba, *nbb;
51
52 assert (a != b);
53
54 a->count++;
55 nba = realloc(a->neighbours, a->count * sizeof(struct edge));
56 if (!nba) {
57 a->count--;
58 return -1;
59 }
60 nba[a->count - 1].distance = distance;
61 nba[a->count - 1].to = b;
62
63 b->count++;
64 nbb = realloc(b->neighbours, b->count * sizeof(struct edge));
65 if (!nbb) {
66 a->count--;
67 b->count--;
68 free(nba);
69 return -1;
70 }
71 nbb[b->count - 1].distance = distance;
72 nbb[b->count - 1].to = a;
73
74 a->neighbours = nba;
75 b->neighbours = nbb;
76 return 0;
77 }
78
79 int node_unlink(struct node* a, struct node* b)
80 {
81 struct edge *nba, *nbb;
82 int i, j;
83 a->count--;
84 nba = malloc(a->count * sizeof(struct edge));
85 if (!nba) {
86 a->count++;
87 return -1;
88 }
89 for (i = 0, j = 0; i < a->count; i++, j++) {
90 if (a->neighbours[i].to != b) {
91 nba[j].to = a->neighbours[i].to;
92 nba[j].distance = a->neighbours[i].distance;
93 } else {
94 j--;
95 }
96 }
97
98 nbb = malloc(b->count * sizeof(struct edge));
99 if (!nbb) {
100 a->count++;
101 b->count++;
102 free(nba);
103 return - 1;
104 }
105 for (i = 0, j = 0; i < b->count; i++, j++) {
106 if (b->neighbours[i].to != a) {
107 nbb[j].to = b->neighbours[i].to;
108 nbb[j].distance = b->neighbours[i].distance;
109 } else {
110 j--;
111 }
112 }
113 free(a->neighbours);
114 free(b->neighbours);
115 a->neighbours = nba;
116 b->neighbours = nbb;
117 return 0;
118 }
119
120 struct graph* graph_new(int n)
121 {
122 struct graph* g;
123
124 srand(time(NULL));
125
126 g = malloc(sizeof(struct graph));
127 if (!g) {
128 return NULL;
129 }
130
131 g->nodes = malloc(n * sizeof(struct node));
132 if (!(g->nodes)) {
133 free(g);
134 return NULL;
135 }
136
137 memset(g->nodes, 0, n * sizeof(struct node));
138 g->count = n;
139 return g;
140 }
141
142 int graph_randomize1(struct graph* g, int l)
143 {
144 int m, n, i, j;
145
146 for (i = 0; i < g->count; i++) {
147 node_randomize(&(g->nodes[i]));
148 }
149
150 for (j = 0; j < l; j++) {
151 m = rand() % g->count;
152 n = rand() % g->count;
153 if ((m == n) || node_is_linked(&(g->nodes[m]), &(g->nodes[n]))) {
154 continue;
155 }
156 if (node_link(&(g->nodes[m]), &(g->nodes[n]), rand())) {
157 goto revert;
158 }
159 }
160
161 return 0;
162 revert:
163 for (i = 0; i < g->count; i++) {
164 node_destroy(&(g->nodes[i]));
165 }
166 memset(g->nodes, 0, g->count * sizeof(struct node));
167 return -1;
168 }
169
170 int graph_randomize2(struct graph* g, int l)
171 {
172 int i, j, n;
173 for (i = 0; i < g->count; i++) {
174 node_randomize(&(g->nodes[i]));
175
176 for (j = 0; j < l; j++) {
177 n = rand() % g->count;
178 if ((i == n) || node_is_linked(&(g->nodes[i]), &(g->nodes[n]))) {
179 continue;
180 }
181 if (node_link(&(g->nodes[i]), &(g->nodes[n]), rand())) {
182 goto revert;
183 }
184 }
185 }
186
187 return 0;
188 revert:
189 for (i = 0; i < g->count; i++) {
190 node_destroy(&(g->nodes[i]));
191 }
192 memset(g->nodes, 0, g->count * sizeof(struct node));
193 return -1;
194 }
195
196 void graph_destroy(struct graph* g)
197 {
198 int i;
199
200 for (i = 0; i < g->count; i++) {
201 free(g->nodes[i].neighbours);
202 }
203 free(g->nodes);
204 free(g);
205 return;
206 }

  ViewVC Help
Powered by ViewVC 1.1.26