From c6b5cae564d85cae5b571ba11cca12541aa09171 Mon Sep 17 00:00:00 2001
From: Manuel Bucher <manuel.bucher@hu-berlin.de>
Date: Mon, 4 Jun 2018 14:54:53 +0200
Subject: [PATCH] Added list to save all obects in memory, because we dont know
 the final amount of all objects

---
 loesung.c | 95 ++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 77 insertions(+), 18 deletions(-)

diff --git a/loesung.c b/loesung.c
index 917ffba..69f9177 100644
--- a/loesung.c
+++ b/loesung.c
@@ -7,8 +7,62 @@
 typedef struct Tile {
     uint32_t x;
     uint32_t y;
+    struct Tile *p_next;
 } Tile;
 
+
+/*************** List von Tiles *********************/
+/** List von Tiles */
+typedef struct List {
+    Tile *p_top;
+    uint32_t size;
+} List;
+
+/** Initialisieren einer leeren Liste */
+void list_init(List *s) {
+    s->p_top = 0;
+    s->size = 0;
+}
+
+/** Hinzufuegen eines leeren Elementes zur Liste
+ *
+ * Voraussetzung: Die Liste muss initialisiert sein.
+ * Rueckgabe: Hinzugefuegtes, initialisiertes Tile
+ */
+Tile* list_push(List *s) {
+    Tile *p_tile = malloc(sizeof(Tile));
+    p_tile->x = 0;
+    p_tile->y = 0;
+    p_tile->p_next = s->p_top;
+    s->p_top = p_tile;
+    s->size++;
+    return p_tile;
+}
+
+/** Entfernen des obersten Elementes von der Liste und zurueckgeben des Tiles
+ *
+ * Der List muss mindestens ein Element besitzen
+ */
+Tile* list_pop(List *s) {
+    Tile *p_tile = s->p_top;
+    s->p_top->p_next = p_tile->p_next;
+    return p_tile;
+}
+
+/** Freigeben des reservierten Speichers von der Liste
+ *
+ * Alle Tiles werden mit free vom speicher deallocaiert
+ */
+void list_free(List *s) {
+    Tile *p_cur = s->p_top;
+    s->p_top = 0;
+    while (p_cur != 0) {
+        Tile *p_next = p_cur->p_next;
+        free(p_cur);
+        p_cur = p_next;
+    }
+}
+
 typedef enum ReadResult {
     RdOk,
     RdEof,
@@ -21,13 +75,15 @@ typedef enum ReadResult {
 typedef struct Field {
     Tile t_min;
     Tile t_max;
-    uint32_t num_tiles;
+    List tiles;
 } Field;
 
 /** Parsen einer Kachel(Tile) aus einer Zeile von StdIn
  *
- * Die Zahlen werden in das uebergebene Struct pKachel geschrieben, sind aber
+ * Die Zahlen werden in das uebergebene Struct pTile geschrieben, sind aber
  * nur gueltig, wenn der Rueckgabewert `Ok` ist.
+ *
+ * Voraussetzung: p_tile muss initialisiert sein
  */
 ReadResult read_line(Tile* p_tile){
     int c = getchar();
@@ -44,7 +100,6 @@ ReadResult read_line(Tile* p_tile){
                     return RdErrTooManyNumbers;
                 }
                 p_cur = (&p_tile->x)+cur_number;
-                *p_cur = 0;
                 cur_whitespace = false;
                 cur_number++;
             }
@@ -109,22 +164,23 @@ ReadResult parse_input(Field *f) {
     f->t_min.y = UINT32_MAX;
     f->t_max.x = 0;
     f->t_max.y = 0;
-    f->num_tiles = 0;
+    // initialisieren der Liste
+    list_init(&f->tiles);
 
     while (1) {
-        Tile t;
-        ReadResult result = read_line(&t);
-        f->num_tiles++;
+        Tile *t = list_push(&f->tiles); // neues Element in die Liste einfuegen
+        ReadResult result = read_line(t);
         switch (result) {
         case RdOk:
             // Reichweite des Feldes ermitteln
-            f->t_min.x = min(f->t_min.x, t.x);
-            f->t_min.y = min(f->t_min.y, t.y);
-            f->t_max.x = max(f->t_max.x, t.x);
-            f->t_max.y = max(f->t_max.x, t.y);
+            f->t_min.x = min(f->t_min.x, t->x);
+            f->t_min.y = min(f->t_min.y, t->y);
+            f->t_max.x = max(f->t_max.x, t->x);
+            f->t_max.y = max(f->t_max.x, t->y);
             break;
         case RdEof:
-            if (f->num_tiles == 1) {
+            list_pop(&f->tiles);
+            if (f->tiles.size == 1) {
                 return RdEof;
             } else {
                 return RdOk;
@@ -143,7 +199,7 @@ int main (int argc,
     switch (result) {
     case RdOk:
         printf("Valider Input\n");
-        printf("Anzahl: %d\n", f.num_tiles);
+        printf("Anzahl: %d\n", f.tiles.size);
         printf("Range(%d, %d), (%d, %d)\n",
                f.t_min.x, f.t_min.y,
                f.t_max.x, f.t_max.y);
@@ -155,20 +211,23 @@ int main (int argc,
         // bei leerer Eingabe nichts ausgeben
         return EXIT_SUCCESS;
     case RdErrIntegerOverflow:
-        fprintf(stderr, "Error in line %d: too big integer\n", f.num_tiles);
+        fprintf(stderr, "Error in line %d: too big integer\n", f.tiles.size);
+        list_free(&f.tiles);
         return EXIT_FAILURE;
     case RdErrNonDigitCharacter:
-        fprintf(stderr, "Error in line %d: invalid character\n", f.num_tiles);
+        fprintf(stderr, "Error in line %d: invalid character\n", f.tiles.size);
+        list_free(&f.tiles);
         return EXIT_FAILURE;
     case RdErrTooFewNumbers:
         fprintf(stderr, "Error in line %d: Too few numbers, expected exactly 2\n",
-               f.num_tiles);
+               f.tiles.size);
+        list_free(&f.tiles);
         return EXIT_FAILURE;
     case RdErrTooManyNumbers:
         fprintf(stderr, "Error in line %d: Too much numbers, expected exactly 2\n",
-               f.num_tiles);
+               f.tiles.size);
+        list_free(&f.tiles);
         return EXIT_FAILURE;
-
     }
     return EXIT_SUCCESS;
 }
-- 
GitLab