diff --git a/loesung.c b/loesung.c index 24ac3c38b0d10da444a5954dcfbd4e1d498de496..e9ee5c3ccc1fbd13bec6f18b795d2e1016fda94c 100644 --- a/loesung.c +++ b/loesung.c @@ -12,6 +12,23 @@ typedef struct Tile { } Tile; +int tile_compare(const void *p, const void *q) { + const Tile *s = *(const Tile**) p; + const Tile *t = *(const Tile**) q; + // als erstes nach x sortieren + if (s->x < t->x) + return -1; + if (s->x > t->x) + return 1; + // danach nach y sortieren + if (s->y < t->y) + return -1; + if (s->y > t->y) + return 1; + return 0; // Elemente sind gleich +} + + /*************** List von Tiles *********************/ /** List von Tiles */ typedef struct List { @@ -32,6 +49,9 @@ void list_init(List *s) { */ Tile* list_push(List *s) { Tile *p_tile = malloc(sizeof(Tile)); + if(p_tile == NULL) { // failed to allocate memory + return NULL; + } p_tile->x = 0; p_tile->y = 0; p_tile->p_next = s->p_top; @@ -76,6 +96,7 @@ typedef enum ReadResult { ReadErrNonDigitCharacter, ReadErrTooFewNumbers, ReadErrTooManyNumbers, + ReadErrOutOfMemory, } ReadResult; typedef struct Field { @@ -161,9 +182,14 @@ void field_init(Field *f) { /** Freigeben des im Heap reservierten speichers des fields f */ void field_drop(Field *f) { - list_free(&f->tile_list); - if(f->tile_array) { + uint32_t num_tiles = f->tile_list.size; + if(f->tile_array != NULL) { + for(uint32_t i = 0; i < num_tiles; i++) { + free(f->tile_array[i]); + } free(f->tile_array); + } else { + list_free(&f->tile_list); } } @@ -187,6 +213,9 @@ void field_drop(Field *f) { ReadResult field_init_tile_list(Field *f) { while (1) { Tile *t = list_push(&f->tile_list); // neues Element in die Liste einfuegen + if (t == NULL) { + return ReadErrOutOfMemory; + } ReadResult result = read_line(t); switch (result) { case ReadOk: @@ -209,18 +238,33 @@ ReadResult field_init_tile_list(Field *f) { } } +typedef enum MallocResult { + MallocFailed, + MallocOk, +} MallocResult; /** Initialisieren des Tile-Arrays * * Laufzeit: O(n) */ -void field_init_tile_array(Field *f) { +MallocResult field_init_tile_array(Field *f) { f->tile_array = malloc(f->tile_list.size * sizeof(Tile*)); + if(f->tile_array == NULL) { + return MallocFailed; + } Tile *cur = f->tile_list.p_top; for (uint32_t i = 0; i < f->tile_list.size; i++) { f->tile_array[i] = cur; cur = cur->p_next; } + return MallocOk; +} + +void field_print(Field *f) { + printf("# Array\n"); + for (uint32_t i = 0; i < f->tile_list.size; i++) { + printf("%d %d\n", f->tile_array[i]->x, f->tile_array[i]->y); + } } int main (void) @@ -231,7 +275,6 @@ int main (void) ReadResult result = field_init_tile_list(&field); // lesen des Inputs switch (result) { case ReadOk: - field_init_tile_array(&field); break; case ReadEof: // bei leerer Eingabe nichts ausgeben @@ -254,7 +297,16 @@ int main (void) field.tile_list.size); field_drop(&field); return EXIT_FAILURE; + case ReadErrOutOfMemory: + fprintf(stderr, "Error in line %d: Failed to allocate more memory", + field.tile_list.size); + return EXIT_FAILURE; + } + // turn the list into an array + if(field_init_tile_array(&field) == MallocFailed) { + fprintf(stderr, "Error: Failed to allocate enough memory"); } + qsort(field.tile_array, field.tile_list.size, sizeof(Tile*), tile_compare); field_drop(&field); return EXIT_SUCCESS;