spacepaste

  1.  
  2. $ ./new
  3. last_ref = 5
  4. last_ref = 15
  5. last_ref = 25
  6. last_ref = 25
  7. last_ref = 28
  8. last_ref = 32
  9. last_ref = 32
  10. last_ref = 35
  11. last_ref = 37
  12. last_ref = 41
  13. last_ref = 41
  14. last_ref = 45
  15. last_ref = 45
  16. last_ref = 48
  17. last_ref = 52
  18. last_ref = 52
  19. last_ref = 55
  20. last_ref = 57
  21. last_ref = 61
  22. last_ref = 61
  23. 0 -> 1
  24. branch start
  25. branch choice start
  26. 1 -> 2
  27. 2 -> 3
  28. branch start
  29. branch choice start
  30. 3 -> 4
  31. 4 -> 25
  32. branch choice end
  33. branch end
  34. branch choice end
  35. branch choice start
  36. 5 -> 6
  37. 6 -> 7
  38. branch start
  39. branch choice start
  40. 7 -> 8
  41. 8 -> 9
  42. branch start
  43. branch choice start
  44. 9 -> 10
  45. 10 -> 11
  46. branch start
  47. branch choice start
  48. branch start
  49. branch choice start
  50. 11 -> 12
  51. 12 -> 13
  52. branch start
  53. branch choice start
  54. 13 -> 14
  55. 14 -> 25
  56. branch choice end
  57. branch end
  58. branch choice end
  59. branch choice start
  60. 15 -> 16
  61. 16 -> 17
  62. branch start
  63. branch choice start
  64. 17 -> 18
  65. 18 -> 19
  66. branch start
  67. branch choice start
  68. 19 -> 20
  69. 20 -> 21
  70. branch start
  71. branch choice start
  72. 21 -> 22
  73. 22 -> 23
  74. branch start
  75. branch choice start
  76. 23 -> 24
  77. 24 -> 25
  78. branch choice end
  79. branch end
  80. 25 -> 26
  81. 26 -> 27
  82. 27 -> 32
  83. branch choice end
  84. branch choice start
  85. 28 -> 29
  86. 29 -> 30
  87. branch start
  88. branch choice start
  89. 30 -> 31
  90. 31 -> 32
  91. branch choice end
  92. branch end
  93. 32 -> 33
  94. 33 -> 34
  95. 34 -> 41
  96. branch choice end
  97. branch end
  98. branch start
  99. branch choice start
  100. 35 -> 36
  101. 36 -> 41
  102. branch choice end
  103. branch end
  104. branch choice end
  105. branch choice start
  106. 37 -> 38
  107. 38 -> 39
  108. branch start
  109. branch choice start
  110. 39 -> 40
  111. 40 -> 41
  112. branch choice end
  113. branch end
  114. branch choice end
  115. branch end
  116. branch choice end
  117. branch end
  118. branch choice end
  119. branch end
  120. 41 -> 42
  121. 42 -> 43
  122. branch start
  123. branch choice start
  124. 43 -> 44
  125. 44 -> 45
  126. branch choice end
  127. branch end
  128. 45 -> 46
  129. 46 -> 47
  130. 47 -> 52
  131. branch choice end
  132. branch choice start
  133. 48 -> 49
  134. 49 -> 50
  135. branch start
  136. branch choice start
  137. 50 -> 51
  138. 51 -> 52
  139. branch choice end
  140. branch end
  141. 52 -> 53
  142. 53 -> 54
  143. 54 -> 61
  144. branch choice end
  145. branch end
  146. branch start
  147. branch choice start
  148. 55 -> 56
  149. 56 -> 61
  150. branch choice end
  151. branch end
  152. branch choice end
  153. branch choice start
  154. 57 -> 58
  155. 58 -> 59
  156. branch start
  157. branch choice start
  158. 59 -> 60
  159. 60 -> 61
  160. branch choice end
  161. branch end
  162. branch choice end
  163. branch end
  164. branch choice end
  165. branch end
  166. branch choice end
  167. branch end
  168. 61 -> 62
  169. NULL
  170. freed 438 nodes
  171. $ cat new.c
  172. #include <stdbool.h>
  173. #include <stdio.h>
  174. #include <stdlib.h>
  175. #include <string.h>
  176. #define pp(x) printf("%s = %p\n", #x, x);
  177. #define pi(x) printf("%s = %d\n", #x, x);
  178. #define pc(x) printf("%s = %c\n", #x, x);
  179. #define psize_t(x) printf("%s = %zu\n", #x, x);
  180. // A C program to demonstrate linked list based implementation of queue
  181. // A linked list (LL) node to store a queue entry
  182. int index_start = -1;
  183. int ref_start = 0;
  184. int global_indent = 0;
  185. #define node_init(t, i, r, nc, n) t->index = i; t->ref = r; t->next_count = nc; t->next = n; t->level = global_indent;
  186. #define STORE_NORMAL 1
  187. #define STORE_EMPTY 2
  188. #define NODE_TYPE_NORMAL 1
  189. #define NODE_TYPE_BRANCH_START 2
  190. #define NODE_TYPE_BRANCH_END 3
  191. #define NODE_TYPE_BRANCH_CHOICE_START 4
  192. #define NODE_TYPE_BRANCH_CHOICE_END 5
  193. #define POINTER_LIST_TYPE int
  194. POINTER_LIST_TYPE ** ptr_list = NULL;
  195. ssize_t ptr_list_size = 0;
  196. int last_ref = 0;
  197. int ptr_add(POINTER_LIST_TYPE * ptr) {
  198. if (!ptr) return -1;
  199. if (!ptr_list) {
  200. ptr_list = malloc(sizeof(ptr_list)*2);
  201. ptr_list_size++;
  202. }
  203. else if (ptr_list) {
  204. ptr_list = realloc(ptr_list, sizeof(ptr_list)*(ptr_list_size+1));
  205. }
  206. ptr_list[ptr_list_size-1] = ptr;
  207. ptr_list_size++;
  208. ptr_list[ptr_list_size-1] = NULL;
  209. return 0;
  210. }
  211. int ptr_print(void) {
  212. if (!ptr_list) return -1;
  213. POINTER_LIST_TYPE ** pl;
  214. for (pl = ptr_list; *pl; pl++) pp(*pl);
  215. return 0;
  216. }
  217. int ptr_set(POINTER_LIST_TYPE data) {
  218. if (!ptr_list) return -1;
  219. POINTER_LIST_TYPE ** pl;
  220. for (pl = ptr_list; *pl; pl++) **pl = data;
  221. return 0;
  222. }
  223. int ptr_free(void) {
  224. if (!ptr_list) return -1;
  225. POINTER_LIST_TYPE ** pl;
  226. for (pl = ptr_list; *pl; pl++) *pl = NULL;
  227. free(ptr_list);
  228. ptr_list = NULL;
  229. ptr_list_size = 0;
  230. return 0;
  231. }
  232. struct QNode
  233. {
  234. int level;
  235. int index;
  236. int ref;
  237. int next_count;
  238. int type;
  239. struct QNode **next;
  240. };
  241. // The queue, front stores the front node of LL and rear stores ths
  242. // last node of LL
  243. struct Queue
  244. {
  245. struct QNode *front, *rear;
  246. };
  247. // A utility function to create a new linked list node.
  248. struct QNode* newNode(int type)
  249. {
  250. struct QNode *temp = (struct QNode*)malloc(sizeof(struct QNode));
  251. if (type == STORE_NORMAL) {
  252. node_init(temp, index_start++, ref_start++, 0, NULL);
  253. } else if (type == STORE_EMPTY) {
  254. node_init(temp, 0, 0, 0, NULL);
  255. }
  256. return temp;
  257. }
  258. // A utility function to create an empty queue
  259. struct Queue *createQueue()
  260. {
  261. struct Queue *q = (struct Queue*)malloc(sizeof(struct Queue));
  262. q->front = q->rear = NULL;
  263. return q;
  264. }
  265. int prev_type = 0;
  266. int curr_type = 0;
  267. void store_asm(struct Queue *q, int type)
  268. {
  269. if (curr_type) prev_type = curr_type;
  270. curr_type = type;
  271. // Create a new LL node
  272. int t = 0;
  273. if (type == NODE_TYPE_NORMAL) t = STORE_NORMAL;
  274. else if (
  275. type == NODE_TYPE_BRANCH_START
  276. ||
  277. type == NODE_TYPE_BRANCH_END
  278. ||
  279. type == NODE_TYPE_BRANCH_CHOICE_START
  280. ||
  281. type == NODE_TYPE_BRANCH_CHOICE_END
  282. ) t = STORE_EMPTY;
  283. struct QNode *temp = newNode(t);
  284. temp->type = type;
  285. // If queue is empty, then new node is front and rear both
  286. if (q->rear == NULL)
  287. {
  288. q->front = q->rear = temp;
  289. if (!q->rear->next) {
  290. q->rear->next_count = 1;
  291. q->rear->next = malloc(sizeof(struct QNode)*q->rear->next_count);
  292. } else {
  293. q->rear->next_count++;
  294. q->rear->next = realloc(q->rear->next, sizeof(struct QNode)*q->rear->next_count);
  295. }
  296. return;
  297. }
  298. if (prev_type == NODE_TYPE_NORMAL) {
  299. if (type == NODE_TYPE_BRANCH_CHOICE_END) {
  300. // pp(&q->rear->ref)
  301. last_ref = q->rear->ref;
  302. pi(last_ref);
  303. ptr_add(&q->rear->ref);
  304. }
  305. }
  306. else if(type == NODE_TYPE_NORMAL && prev_type == NODE_TYPE_BRANCH_END) {
  307. pi(last_ref);
  308. ptr_set(last_ref);
  309. ptr_free();
  310. }
  311. // Add the new node at the end of queue and change rear
  312. q->rear->next[q->rear->next_count-1] = temp;
  313. q->rear = temp;
  314. if (!q->rear->next) {
  315. q->rear->next_count = 1;
  316. q->rear->next = malloc(sizeof(struct QNode)*q->rear->next_count);
  317. } else {
  318. q->rear->next_count++;
  319. q->rear->next = realloc(q->rear->next, sizeof(struct QNode)*q->rear->next_count);
  320. }
  321. }
  322. struct QNode * load_asm(struct Queue **q)
  323. {
  324. // If queue is empty, return NULL.
  325. if ((q) == NULL) return NULL;
  326. if ((*q) == NULL) return NULL;
  327. if ((*q)->front == NULL)
  328. return NULL;
  329. // Store previous front and move front one node ahead
  330. struct QNode *temp = (*q)->front;
  331. (*q)->front = (*q)->front->next[0];
  332. // If front becomes NULL, then change rear also as NULL
  333. if ((*q)->front == NULL)
  334. (*q)->rear = NULL;
  335. return temp;
  336. }
  337. void add(struct Queue **q) {
  338. if (!(*q)) (*q) = createQueue();
  339. store_asm((*q), NODE_TYPE_NORMAL);
  340. }
  341. #define add_indent(indent) { int i = 0; for (; i < indent; i++) printf(" "); }
  342. struct Queue * list = NULL;
  343. void print(struct QNode * p) {
  344. int indentation = 0;
  345. while(p) {
  346. indentation = p->level;
  347. add_indent(indentation);
  348. if (p->type == NODE_TYPE_BRANCH_START) {
  349. add_indent(indentation);
  350. printf("branch start\n");
  351. }
  352. else if (p->type == NODE_TYPE_BRANCH_END) {
  353. add_indent(indentation);
  354. printf("branch end\n");
  355. }
  356. else if (p->type == NODE_TYPE_BRANCH_CHOICE_START) {
  357. add_indent(indentation);
  358. printf("branch choice start\n");
  359. }
  360. else if (p->type == NODE_TYPE_BRANCH_CHOICE_END) {
  361. add_indent(indentation);
  362. printf("branch choice end\n");
  363. }
  364. else if (p->type == NODE_TYPE_NORMAL) {
  365. add_indent(indentation);
  366. printf("%d -> %d\n", p->index, p->ref);
  367. }
  368. if (p->next) p = p->next[0];
  369. else p = NULL;
  370. }
  371. add_indent(indentation);
  372. puts("NULL");
  373. }
  374. void add_branch(struct Queue **q) {
  375. if (!(*q)) (*q) = createQueue();
  376. store_asm((*q), NODE_TYPE_BRANCH_START);
  377. global_indent++;
  378. }
  379. void end_branch(struct Queue **q) {
  380. global_indent--;
  381. if (!(*q)) (*q) = createQueue();
  382. store_asm((*q), NODE_TYPE_BRANCH_END);
  383. }
  384. void add_branch_choice(struct Queue **q) {
  385. if (!(*q)) (*q) = createQueue();
  386. store_asm((*q), NODE_TYPE_BRANCH_CHOICE_START);
  387. global_indent++;
  388. }
  389. void end_branch_choice(struct Queue **q) {
  390. global_indent--;
  391. if (!(*q)) (*q) = createQueue();
  392. store_asm((*q), NODE_TYPE_BRANCH_CHOICE_END);
  393. }
  394. int main(void) {
  395. index_start = 0;
  396. ref_start = 1;
  397. add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); add(&list); add(&list); add(&list); end_branch_choice(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); add(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); end_branch(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); add(&list); add(&list); add(&list); end_branch_choice(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); add(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); add_branch_choice(&list); add(&list); add(&list); add_branch(&list); add_branch_choice(&list); add(&list); add(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); end_branch(&list); end_branch_choice(&list); end_branch(&list); add(&list);
  398. print(list->front);
  399. ptr_print();
  400. // this part should be left to the garbage collector to clean up
  401. struct QNode * node = load_asm(&list);
  402. ssize_t nodes = 0;
  403. while (node != NULL) {
  404. if (node->next) {
  405. if (node->next[0]) {
  406. free(node->next[0]);
  407. nodes++;
  408. }
  409. free(node->next);
  410. nodes++;
  411. }
  412. free(node);
  413. nodes++;
  414. node = load_asm(&list);
  415. }
  416. free(list);
  417. nodes++;
  418. printf("freed %zu node%s\n", nodes, nodes==1?"":"s");
  419. return 0;
  420. }
  421.