9 Commits
21 changed files with 304 additions and 83 deletions

No files matched your search

+40
View File
@@ -0,0 +1,40 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug test_stack",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/test_stack.exe",
"cwd": "${workspaceFolder}",
"MIMode": "gdb",
"miDebuggerPath": "C:/ProgramData/mingw64/mingw64/bin/gdb.exe",
"preLaunchTask": "Build via Makefile"
},
{
"name": "Debug test_numbers",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/test_numbers.exe",
"cwd": "${workspaceFolder}",
"MIMode": "gdb",
"miDebuggerPath": "C:/ProgramData/mingw64/mingw64/bin/gdb.exe",
"preLaunchTask": "Build via Makefile"
},
{
"name": "Debug test_bintree",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/test_bintree.exe",
"cwd": "${workspaceFolder}",
"MIMode": "gdb",
"miDebuggerPath": "C:/ProgramData/mingw64/mingw64/bin/gdb.exe",
"preLaunchTask": "Build via Makefile"
}
]
}
+27
View File
@@ -0,0 +1,27 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build via Makefile",
"type": "shell",
"command": "mingw32-make",
"args": ["${input:target}"],
"options": {
"cwd": "${workspaceFolder}"
},
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": "$gcc"
}
],
"inputs": [
{
"id": "target",
"type": "pickString",
"description": "Welches Makefile-Target soll gebaut werden?",
"options": ["test_stack", "test_numbers", "test_bintree", "doble", "unitTests"]
}
]
}
+7 -2
View File
@@ -93,6 +93,11 @@ TreeNode *addToTree(TreeNode *wurzel,
return wurzel; return wurzel;
} }
/*
Die Funktion gibt bei jedem Aufruf das nächste Element des Binärbaums in **Inorder-Reihenfolge**
zurück und merkt sich intern, wo sie zuletzt war.
*/
void *nextTreeData(TreeNode *wurzel) void *nextTreeData(TreeNode *wurzel)
{ {
static StackNode *iteratorStack = NULL; // interner Zustand über Aufrufe hinweg static StackNode *iteratorStack = NULL; // interner Zustand über Aufrufe hinweg
@@ -110,8 +115,8 @@ void *nextTreeData(TreeNode *wurzel)
return NULL; return NULL;
// Nächsten Knoten holen (oberstes Stack-Element) // Nächsten Knoten holen (oberstes Stack-Element)
TreeNode *aktuellerKnoten = (TreeNode *)top(iteratorStack); TreeNode *aktuellerKnoten = (TreeNode *)top(iteratorStack); //Oberstes Element zurück
iteratorStack = pop(iteratorStack); iteratorStack = pop(iteratorStack); // entfernt Oberstes Element
// Falls rechter Teilbaum existiert: dessen linke Kette ablegen // Falls rechter Teilbaum existiert: dessen linke Kette ablegen
if (aktuellerKnoten->right != NULL) if (aktuellerKnoten->right != NULL)
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+3 -3
View File
@@ -1,10 +1,10 @@
Player1;19887
Player1;19843
Lena;19811 Lena;19811
Lena;19702 Lena;19702
Player1;19578
player_name;9981 player_name;9981
Lena;9980 Lena;9980
Lena;9978 Lena;9978
Lena;9978 Lena;9978
Lena;9976 Lena;9976
Lena;9975
Lena;9971
Lena;9965
BIN
View File
Binary file not shown.
+126 -38
View File
@@ -1,3 +1,4 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>
@@ -5,70 +6,135 @@
#include "numbers.h" #include "numbers.h"
#include "bintree.h" #include "bintree.h"
// helper comparator for unsigned int for bintree /**
* @brief Vergleichsfunktion für unsigned int-Werte zur Verwendung im Binärbaum.
*
* Diese Funktion wird von der Binärbaum-Implementierung genutzt, um die
* Ordnung der Knoten zu bestimmen. Sie vergleicht die dereferenzierten
* unsigned int-Werte a und b.
*
* @param a Pointer auf einen unsigned int-Wert (linker Operand)
* @param b Pointer auf einen unsigned int-Wert (rechter Operand)
* @return -1, falls *a < *b; 1, falls *a > *b; 0, falls *a == *b
*/
static int compareUInt(const void *a, const void *b) static int compareUInt(const void *a, const void *b)
{ {
unsigned int va = *(const unsigned int *)a; unsigned int va = *(const unsigned int *)a;
unsigned int vb = *(const unsigned int *)b; unsigned int vb = *(const unsigned int *)b;
if(va < vb) return -1; if (va < vb) return -1;
if(va > vb) return 1; if (va > vb) return 1;
return 0; return 0;
} }
// comparator for qsort (unsigned int) /**
* @brief Vergleichsfunktion für qsort() zur Sortierung von unsigned int-Arrays.
*
* @param a Pointer auf einen Arrayeintrag
* @param b Pointer auf einen Arrayeintrag
* @return -1, 0, 1 analog zu compareUInt()
*/
static int qsort_uint_cmp(const void *a, const void *b) static int qsort_uint_cmp(const void *a, const void *b)
{ {
unsigned int va = *(const unsigned int *)a; unsigned int va = *(const unsigned int *)a;
unsigned int vb = *(const unsigned int *)b; unsigned int vb = *(const unsigned int *)b;
if(va < vb) return -1; if (va < vb) return -1;
if(va > vb) return 1; if (va > vb) return 1;
return 0; return 0;
} }
// Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries. /**
// Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while * @brief Erzeugt ein Array aus len Zufallszahlen im Bereich [1 .. 2*len],
// creating random numbers. * das genau einen duplizierten Wert enthält (d. h. len-1 eindeutige + 1 Duplikat),
* und mischt die Reihenfolge zufällig.
*
* Funktionsweise:
* - Es werden zunächst len-1 eindeutige Zufallszahlen erzeugt. Die Eindeutigkeit wird
* mithilfe eines Binärsuchbaums (BST) geprüft: addToTree() fügt die Zahl ein
* und signalisiert per isDup, ob sie bereits vorhanden war.
* - Anschließend wird eine der bereits erzeugten Zahlen zufällig ausgewählt und
* noch einmal an das Ende des Arrays geschrieben, um das geforderte Duplikat sicherzustellen.
* - Zum Schluss wird das gesamte Array mittels Fisher–Yates-Algorithmus gemischt.
*
* Fehlerbehandlung:
* - Bei len < 2 wird NULL zurückgegeben, da das Problem ein Duplikat erfordert.
* - Bei Speicher- oder Baum-Insertionsfehlern wird aufgeräumt und NULL zurückgegeben.
* Wichtig: Der Baumzeiger root wird erst nach erfolgreichem Insert aktualisiert,
* um im Fehlerfall kein bereits aufgebautes Teilbaum-Objekt zu verlieren.
*
* Randbedingungen / Annahmen:
* - addToTree(root, &val, sizeof(val), compareUInt, &isDup) setzt isDup:
* isDup == 1 bedeutet „Duplikat gefunden, Baum unverändert“,
* isDup == 0 bedeutet „neuer Wert eingefügt (oder Fehler)“.
* - Bei Speicherfehler gibt addToTree NULL zurück und isDup bleibt 0.
* - clearTree(root) darf mit NULL-Argument aufgerufen werden (No-Op).
*
* Komplexität:
* - Durchschnittlich O(len * log(len)) für die len-1 Einfügungen in den BST.
* - Shuffle in O(len).
*
* @param len Anzahl der zu erzeugenden Werte (muss >= 2 sein)
* @return Pointer auf ein Array mit len Einträgen bei Erfolg; NULL bei Fehlern
*/
unsigned int *createNumbers(unsigned int len) unsigned int *createNumbers(unsigned int len)
{ {
if(len < 2) if (len < 2)
return NULL; return NULL;
unsigned int *numbers = (unsigned int *)malloc(sizeof(unsigned int) * len); unsigned int *numbers = (unsigned int *)malloc(sizeof(unsigned int) * len);
if(numbers == NULL) if (numbers == NULL)
return NULL; return NULL;
// seed once // Zufallszahlengenerator nur einmal pro Prozess initialisieren.
srand((unsigned int)time(NULL)); // Hintergrund: Wird createNumbers mehrfach schnell hintereinander gerufen,
// kann time(NULL) identische Seeds liefern und damit identische Zahlenfolgen erzeugen.
static int seeded = 0;
if (!seeded) {
srand((unsigned int)time(NULL));
seeded = 1;
}
TreeNode *root = NULL; TreeNode *root = NULL;
unsigned int range = 2 * len; unsigned int range = 2 * len;
// create len-1 unique numbers
for(unsigned int i = 0; i < len - 1; i++) // Schritt 1: len-1 eindeutige Zufallszahlen erzeugen
for (unsigned int i = 0; i < len - 1; i++)
{ {
unsigned int val; unsigned int val;
int isDup = 0; int isDup;
// try until a unique number is inserted
do // Wiederholen, bis eine wirklich neue Zahl eingefügt wurde
for (;;)
{ {
val = (unsigned int)(rand() % range) + 1; // [1..2*len] isDup = 0; // vor jedem Insert zurücksetzen, um „alte“ Werte zu vermeiden
root = addToTree(root, &val, sizeof(val), compareUInt, &isDup); val = (unsigned int)(rand() % range) + 1; // Wertebereich [1 .. 2*len]
// if addToTree returned NULL due to allocation failure, cleanup and return NULL
if(root == NULL && isDup == 0) // addToTree kann bei Erfolg einen (ggf. neuen) Wurzelzeiger liefern.
{ // Zur Vermeidung eines Speicherlecks bei Fehlern zunächst in temp speichern.
TreeNode *newRoot = addToTree(root, &val, sizeof(val), compareUInt, &isDup);
if (newRoot == NULL && isDup == 0) {
// Vermutlich Speicher-/Insertionsfehler: aufräumen und abbrechen
free(numbers); free(numbers);
clearTree(root); clearTree(root); // root zeigt noch auf den gültigen Teilbaum
return NULL; return NULL;
} }
} while(isDup);
numbers[i] = val; if (!isDup) {
// Einfügen war erfolgreich und der Wert ist eindeutig.
root = newRoot;
numbers[i] = val;
break;
}
// Andernfalls Duplikat: Neue Zufallszahl versuchen.
}
} }
// duplicate one existing random entry // Schritt 2: Eine der bestehenden Zahlen zufällig duplizieren
unsigned int idx = (unsigned int)(rand() % (len - 1)); unsigned int idx = (unsigned int)(rand() % (len - 1)); // Index im Bereich [0 .. len-2]
numbers[len - 1] = numbers[idx]; numbers[len - 1] = numbers[idx];
// shuffle array (Fisher-Yates) // Schritt 3: Fisher–Yates-Shuffle über das gesamte Array
for(unsigned int i = len - 1; i > 0; i--) for (unsigned int i = len - 1; i > 0; i--)
{ {
unsigned int j = (unsigned int)(rand() % (i + 1)); unsigned int j = (unsigned int)(rand() % (i + 1));
unsigned int tmp = numbers[i]; unsigned int tmp = numbers[i];
@@ -76,31 +142,53 @@ unsigned int *createNumbers(unsigned int len)
numbers[j] = tmp; numbers[j] = tmp;
} }
// free tree resources // Aufräumen: Baum freigeben
clearTree(root); clearTree(root);
return numbers; return numbers;
} }
// Returns only the only number in numbers which is present twice. Returns zero on errors. /**
* @brief Findet den einzigen duplizierten Wert in einem Array aus len unsigned int.
*
* Funktionsweise:
* - Es wird eine Kopie des Eingabearrays erstellt, um die Reihenfolge des
* Originalarrays nicht zu verändern.
* - Die Kopie wird mittels qsort() aufsteigend sortiert.
* - Beim Durchlauf werden benachbarte Elemente verglichen. Da genau ein Wert
* doppelt vorkommt, finden wir ihn als erstes Paar gleicher Nachbarn.
*
* Fehlerbehandlung:
* - Bei ungültigen Parametern (numbers == NULL oder len < 2) wird 0 geliefert.
* - Bei Speicherfehlern beim Kopieren ebenfalls 0.
*
* Komplexität:
* - Sortieren in O(len * log(len)), anschließender Linearpass O(len).
*
* @param numbers Pointer auf das Eingabearray
* @param len Länge des Arrays (muss >= 2 sein)
* @return Der doppelte Wert; 0 bei Fehlern oder falls kein Duplikat gefunden wurde
* (gemäß Aufgabenstellung sollte aber genau ein Duplikat existieren).
*/
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{ {
if(numbers == NULL || len < 2) if (numbers == NULL || len < 2)
return 0; return 0;
// make a copy so original array order is not modified by caller expectation // Kopie erstellen, damit das Original unangetastet bleibt
unsigned int *copy = (unsigned int *)malloc(sizeof(unsigned int) * len); unsigned int *copy = (unsigned int *)malloc(sizeof(unsigned int) * len);
if(copy == NULL) if (copy == NULL)
return 0; return 0;
memcpy(copy, numbers, sizeof(unsigned int) * len); memcpy(copy, numbers, sizeof(unsigned int) * len);
// Sortieren der Kopie
qsort(copy, len, sizeof(unsigned int), qsort_uint_cmp); qsort(copy, len, sizeof(unsigned int), qsort_uint_cmp);
// Linearer Scan: erstes Paar identischer Nachbarn ist das Duplikat
unsigned int result = 0; unsigned int result = 0;
for(unsigned int i = 0; i + 1 < len; i++) for (unsigned int i = 0; i + 1 < len; i++)
{ {
if(copy[i] == copy[i+1]) if (copy[i] == copy[i + 1]) {
{
result = copy[i]; result = copy[i];
break; break;
} }
BIN
View File
Binary file not shown.
+5 -5
View File
@@ -1,15 +1,15 @@
#include <stdlib.h> #include <stdlib.h>
#include "stack.h" #include "stack.h"
// Pushes data as pointer onto the stack. // Push Daten auf den Stack legen.
StackNode *push(StackNode *stack, void *data) StackNode *push(StackNode *stack, void *data)
{ {
StackNode *node = (StackNode *)malloc(sizeof(StackNode)); StackNode *node = malloc(sizeof(StackNode));
if(node == NULL) if(node == NULL)
return stack; // allocation failed -> return unchanged stack return stack; // allocation failed -> return unchanged stack
node->data = data; node->data = data; // Setze Daten
node->next = stack; node->next = stack; // Setze nächsten Knoten auf aktuellen Stack
return node; return node;
} }
@@ -21,7 +21,7 @@ StackNode *pop(StackNode *stack)
return NULL; return NULL;
StackNode *next = stack->next; StackNode *next = stack->next;
// Do NOT free stack->data here; caller owns the pointed data // Speicher des aktuellen Knotens freigeben
free(stack); free(stack);
return next; return next;
} }
BIN
View File
Binary file not shown.
+8 -5
View File
@@ -3,7 +3,7 @@
#include <string.h> #include <string.h>
#include "bintree.h" #include "bintree.h"
// comparator for unsigned int values stored by value in heap // Vergleichsfunktion für unsigned int
static int cmp_uint_ptr(const void *a, const void *b) static int cmp_uint_ptr(const void *a, const void *b)
{ {
unsigned int va = *(const unsigned int *)a; unsigned int va = *(const unsigned int *)a;
@@ -19,7 +19,7 @@ int main(void)
unsigned int vals[] = {5, 2, 8, 1, 3, 7, 9}; unsigned int vals[] = {5, 2, 8, 1, 3, 7, 9};
const size_t n = sizeof(vals)/sizeof(vals[0]); const size_t n = sizeof(vals)/sizeof(vals[0]);
// insert values (copy made by addToTree) // Werte in den Baum einfügen
for(size_t i = 0; i < n; i++) for(size_t i = 0; i < n; i++)
{ {
int isDup = 0; int isDup = 0;
@@ -27,22 +27,25 @@ int main(void)
if(root == NULL && isDup == 0) { fprintf(stderr, "addToTree allocation failed\n"); return 1; } if(root == NULL && isDup == 0) { fprintf(stderr, "addToTree allocation failed\n"); return 1; }
} }
// Baumgröße prüfen
unsigned int sz = treeSize(root); unsigned int sz = treeSize(root);
if(sz != n) { fprintf(stderr, "treeSize expected %zu got %u\n", n, sz); clearTree(root); return 2; } if(sz != n) { fprintf(stderr, "treeSize expected %zu got %u\n", n, sz); clearTree(root); return 2; }
// inorder traversal using nextTreeData // Inorder-Traversierung (muss sortiert sein)
unsigned int last = 0; unsigned int last = 0;
int first = 1; int first = 1;
unsigned int *data = nextTreeData(root); unsigned int *data = nextTreeData(root);
while(data != NULL) while(data != NULL)
{ {
unsigned int v = *data; unsigned int v = *data;
// Prüfen, ob Reihenfolge korrekt ist
if(!first && v < last) { fprintf(stderr, "inorder traversal not sorted: %u after %u\n", v, last); clearTree(root); return 3; } if(!first && v < last) { fprintf(stderr, "inorder traversal not sorted: %u after %u\n", v, last); clearTree(root); return 3; }
last = v; first = 0; last = v; first = 0;
data = nextTreeData(NULL); data = nextTreeData(NULL); // nächstes Element holen
} }
clearTree(root); clearTree(root); // Speicher freigeben
printf("test_bintree: OK\n"); printf("test_bintree: OK\n");
return 0; return 0;
} }
+69 -19
View File
@@ -1,41 +1,91 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "numbers.h" #include "numbers.h"
/**
* @brief Selbsttest für createNumbers() und getDuplicate().
*
* Erzeugt ein Array aus len Zufallszahlen mit genau einem duplizierten Wert,
* validiert die Eigenschaften per Zähl-Array (Wertebereich, Häufigkeiten)
* und prüft anschließend, ob getDuplicate() dasselbe Duplikat ermittelt.
*
* Rückgabecodes:
* 0: OK
* 1: createNumbers() fehlgeschlagen
* 2: Speicherfehler für counts
* 3: Wert außerhalb des Bereichs [1..2*len]
* 4: Ein Wert erscheint öfter als zweimal
* 5: Nicht genau ein Duplikat gefunden
* 6: getDuplicate() liefert anderes Ergebnis als Zählung
*/
int main(void) int main(void)
{ {
unsigned int len = 100; unsigned int len = 100; // Anzahl zu erzeugender Zahlen
unsigned int *nums = createNumbers(len); unsigned int *nums = createNumbers(len);
if(nums == NULL) { fprintf(stderr, "createNumbers returned NULL\n"); return 1; } if (nums == NULL) {
fprintf(stderr, "createNumbers returned NULL\n");
// count occurrences return 1; // Erzeugung fehlgeschlagen
unsigned int maxVal = 2 * len;
unsigned int *counts = calloc(maxVal + 1, sizeof(unsigned int));
if(counts == NULL) { free(nums); return 2; }
for(unsigned int i = 0; i < len; i++)
{
if(nums[i] > maxVal) { fprintf(stderr, "value out of expected range\n"); free(nums); free(counts); return 3; }
counts[nums[i]]++;
} }
unsigned int maxVal = 2 * len; // Erlaubter Bereich: [1 .. 2*len]
// Zähl-Array für Häufigkeiten pro Wert (Index 0 bleibt ungenutzt)
unsigned int *counts = calloc(maxVal + 1, sizeof(unsigned int));
if (counts == NULL) {
free(nums);
return 2; // Speicherfehler bei counts
}
// Häufigkeiten bestimmen und gleichzeitig Bereich prüfen
for (unsigned int i = 0; i < len; i++) {
unsigned int v = nums[i];
if (v == 0 || v > maxVal) { // sollte nicht passieren, wenn createNumbers korrekt ist
fprintf(stderr, "value out of expected range\n");
free(nums);
free(counts);
return 3;
}
counts[v]++; // Auftreten des Werts v zählen
}
// Exakt ein Wert muss doppelt vorkommen; keiner darf >2-mal vorkommen
int duplicatesFound = 0; int duplicatesFound = 0;
unsigned int duplicateValue = 0; unsigned int duplicateValue = 0;
for(unsigned int v = 1; v <= maxVal; v++)
{ for (unsigned int v = 1; v <= maxVal; v++) {
if(counts[v] == 2) { duplicatesFound++; duplicateValue = v; } if (counts[v] == 2) {
else if(counts[v] > 2) { fprintf(stderr, "value %u appears more than twice\n", v); free(nums); free(counts); return 4; } duplicatesFound++;
duplicateValue = v; // den doppelten Wert merken
} else if (counts[v] > 2) {
fprintf(stderr, "value %u appears more than twice\n", v);
free(nums);
free(counts);
return 4; // Vertragsbruch: zu häufiges Auftreten
}
// counts[v] == 0 oder 1 sind unkritisch
} }
if(duplicatesFound != 1) { fprintf(stderr, "expected exactly one duplicated value, found %d\n", duplicatesFound); free(nums); free(counts); return 5; } if (duplicatesFound != 1) {
fprintf(stderr, "expected exactly one duplicated value, found %d\n", duplicatesFound);
free(nums);
free(counts);
return 5; // zu wenige/zu viele Duplikate
}
// Ergebnis von getDuplicate() mit der Zählung abgleichen
unsigned int found = getDuplicate(nums, len); unsigned int found = getDuplicate(nums, len);
if(found != duplicateValue) { fprintf(stderr, "getDuplicate returned %u expected %u\n", found, duplicateValue); free(nums); free(counts); return 6; } if (found != duplicateValue) {
fprintf(stderr, "getDuplicate returned %u expected %u\n", found, duplicateValue);
free(nums);
free(counts);
return 6; // Abweichung zwischen Methoden
}
// Ressourcen freigeben und Erfolg melden
free(nums); free(nums);
free(counts); free(counts);
printf("test_numbers: OK (duplicate = %u)\n", duplicateValue); printf("test_numbers: OK (duplicate = %u)\n", duplicateValue);
return 0; return 0;
} }
BIN
View File
Binary file not shown.
+19 -11
View File
@@ -8,37 +8,45 @@ int main(void)
StackNode *s = NULL; StackNode *s = NULL;
// push 3 integers // push 3 integers
int *a = malloc(sizeof(int)); *a = 1; s = push(s, a); int *a = malloc(sizeof(int));
int *b = malloc(sizeof(int)); *b = 2; s = push(s, b); *a = 1;
int *c = malloc(sizeof(int)); *c = 3; s = push(s, c); s = push(s, a);
int *b = malloc(sizeof(int));
*b = 2;
s = push(s, b);
int *c = malloc(sizeof(int));
*c = 3;
s = push(s, c);
// top should be c (3) // oben liegt c (3)
int *topv = (int *)top(s); int *topv = (int *)top(s);
if(topv == NULL || *topv != 3) { fprintf(stderr, "stack top expected 3\n"); return 1; } if(topv == NULL || *topv != 3) { fprintf(stderr, "stack top expected 3\n"); return 1; }
// pop -> now top should be 2 // oben liegt nun 2
s = pop(s); s = pop(s);
topv = (int *)top(s); topv = (int *)top(s);
if(topv == NULL || *topv != 2) { fprintf(stderr, "stack top expected 2 after pop\n"); return 2; } if(topv == NULL || *topv != 2) { fprintf(stderr, "stack top expected 2 after pop\n"); return 2; }
// pop -> now top should be 1 // oben liegt nun 1
s = pop(s); s = pop(s);
topv = (int *)top(s); topv = (int *)top(s);
if(topv == NULL || *topv != 1) { fprintf(stderr, "stack top expected 1 after pop\n"); return 3; } if(topv == NULL || *topv != 1) { fprintf(stderr, "stack top expected 1 after pop\n"); return 3; }
// pop last // letzen Stapelinhalt holen
s = pop(s); s = pop(s);
if(s != NULL) { fprintf(stderr, "stack expected empty after popping all\n"); return 4; } if(s != NULL) { fprintf(stderr, "stack expected empty after popping all\n"); return 4; }
// free stored data (stack does not free data) // Eigenen Speicher freigeben
free(a); free(b); free(c); free(a);
free(b);
free(c);
// test clearStack on empty and small stacks // test clearStack mit leerem Stack
s = push(s, malloc(sizeof(int))); s = push(s, malloc(sizeof(int)));
s = push(s, malloc(sizeof(int))); s = push(s, malloc(sizeof(int)));
clearStack(s); // clearStack must free nodes but not payload; free payloads not necessary because we leaked intentionally for test of API clearStack(s); // clearStack must free nodes but not payload; free payloads not necessary because we leaked intentionally for test of API
// Note: above payloads are not freed (stack API spec); this test ensures clearStack doesn't crash. // Note: above payloads are not freed (stack API spec); this test ensures clearStack doesn't crash.
// Success // Funktioniert alles
printf("test_stack: OK\n"); printf("test_stack: OK\n");
return 0; return 0;
} }
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.