3 Commits
Author SHA1 Message Date
muellermo100295 23dccdfd8d Kommentare hinzugefügt 2025-12-10 22:43:39 +01:00
muellermo100295 0d8a303742 Merge pull request 'Endlich fertig' (#1) from main into MM_Branch
Reviewed-on: #1
2025-12-10 18:21:10 +00:00
Yannik Baumgärtner 416f44ae74 Endlich fertig 2025-12-09 08:00:32 +01:00
30 changed files with 602 additions and 50 deletions

No files matched your search

+132 -20
View File
@@ -1,36 +1,148 @@
#include <stdlib.h>
#include <string.h>
#include "stack.h"
#include "bintree.h"
//TODO: binären Suchbaum implementieren
/* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv),
* `clearTree`: gibt den gesamten Baum frei (rekursiv),
* `treeSize`: zählt die Knoten im Baum (rekursiv),
* `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */
// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
// if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added).
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate)
/*
Schiebt einen Knoten und alle seine linken Nachfolger
(entlang der "linken Kante") auf den Iterator-Stack.
iterStackPtr: Zeiger auf den Top-Zeiger des Stacks (LIFO) für die Wiederholung
knoten: aktueller Startknoten, dessen linke Kette abgelegt wird
*/
static void bintree_pushLefts(StackNode **iterStackPtr, TreeNode *knoten)
{
while (knoten != NULL)
{
*iterStackPtr = push(*iterStackPtr, knoten); // aktuellen Knoten oben auf den Stack legen
knoten = knoten->left; // zum linken Kind weiterlaufen
}
}
// Iterates over the tree given by root. Follows the usage of strtok. If tree is NULL, the next entry of the last tree given is returned in ordering direction.
// Use your implementation of a stack to organize the iterator. Push the root node and all left nodes first. On returning the next element,
// push the top node and push all its left nodes.
void *nextTreeData(TreeNode *root)
{
/*
Fügt eine Kopie der Daten (Speicherbereich von 'data' mit Länge 'dataSize') in den Baum ein.
Die Ordnung wird über 'compareFct' festgelegt.
Duplikate:
- Wenn 'isDuplicate' != NULL übergeben wird: Duplikate werden NICHT eingefügt,
stattdessen wird *isDuplicate = 1 gesetzt (bei neuem Eintrag = 0).
- Wenn 'isDuplicate' == NULL: Duplikate SIND erlaubt; der Duplikat-Eintrag
wird in den rechten Teilbaum eingefügt.
Rückgabe:
- Zeiger auf die (ggf. unveränderte oder neue) Wurzel des Teilbaums.
- NULL bei Speicherfehlern beim Anlegen des ersten Knotens.
*/
TreeNode *addToTree(TreeNode *wurzel,
const void *daten,
size_t datenGroesse,
CompareFctType vergleichFkt,
int *istDuplikat)
{
// Standardmäßig annehmen: kein Duplikat (falls Ausgabefeld vorhanden)
if (istDuplikat != NULL)
*istDuplikat = 0;
// Leerer Baum/Teilbaum: neuen Knoten erzeugen
if (wurzel == NULL)
{
TreeNode *neuerKnoten = (TreeNode *)malloc(sizeof(TreeNode));
if (neuerKnoten == NULL)
return NULL; // Speicherfehler
neuerKnoten->data = malloc(datenGroesse);
if (neuerKnoten->data == NULL)
{
free(neuerKnoten);
return NULL; // Speicherfehler für Datenbereich
}
memcpy(neuerKnoten->data, daten, datenGroesse); // tiefe Kopie der Nutzdaten
neuerKnoten->left = neuerKnoten->right = NULL; // Blatt
return neuerKnoten;
}
// Vergleich der einzufügenden Daten mit dem aktuellen Knoten
int vergleich = vergleichFkt(daten, wurzel->data);
if (vergleich < 0)
{
// links einfügen
wurzel->left = addToTree(wurzel->left, daten, datenGroesse, vergleichFkt, istDuplikat);
}
else if (vergleich > 0)
{
// rechts einfügen
wurzel->right = addToTree(wurzel->right, daten, datenGroesse, vergleichFkt, istDuplikat);
}
else
{
// Gleichheit (potenzielles Duplikat)
if (istDuplikat != NULL)
{
*istDuplikat = 1; // Duplikat erkannt, NICHT einfügen
// keine Änderung am Baum
}
else
{
// Duplikate erlaubt -> konventionell in den rechten Teilbaum einfügen
wurzel->right = addToTree(wurzel->right, daten, datenGroesse, vergleichFkt, istDuplikat);
}
}
return wurzel;
}
// Releases all memory resources (including data copies).
void clearTree(TreeNode *root)
void *nextTreeData(TreeNode *wurzel)
{
static StackNode *iteratorStack = NULL; // interner Zustand über Aufrufe hinweg
// Neuer Baum übergeben -> Iterator zurücksetzen/initialisieren
if (wurzel != NULL)
{
clearStack(iteratorStack); // ggf. alten Stack leeren (Speicher freigeben)
iteratorStack = NULL; // Top-Zeiger zurücksetzen
bintree_pushLefts(&iteratorStack, wurzel); // Wurzel und linke Kette ablegen
}
// Kein weiterer Eintrag?
if (iteratorStack == NULL)
return NULL;
// Nächsten Knoten holen (oberstes Stack-Element)
TreeNode *aktuellerKnoten = (TreeNode *)top(iteratorStack);
iteratorStack = pop(iteratorStack);
// Falls rechter Teilbaum existiert: dessen linke Kette ablegen
if (aktuellerKnoten->right != NULL)
bintree_pushLefts(&iteratorStack, aktuellerKnoten->right);
// Daten des aktuellen Knotens zurückgeben
return aktuellerKnoten->data;
}
// Returns the number of entries in the tree given by root.
unsigned int treeSize(const TreeNode *root)
/*
Gibt den gesamten Baum frei (inkl. der tief kopierten Daten).
*/
void clearTree(TreeNode *wurzel)
{
if (wurzel == NULL)
return;
}
clearTree(wurzel->left);
clearTree(wurzel->right);
free(wurzel->data);
free(wurzel);
}
/*
Liefert die Anzahl der Knoten/Einträge im Teilbaum 'wurzel'.
*/
unsigned int treeSize(const TreeNode *wurzel)
{
if (wurzel == NULL)
return 0;
return 1U + treeSize(wurzel->left) + treeSize(wurzel->right);
}
+65 -11
View File
@@ -1,27 +1,81 @@
#ifndef BINTREE_H
#define BINTREE_H
#include <stdlib.h>
/*
Typdefinition für die Vergleichsfunktion.
Die Funktion muss zwei Datenzeiger vergleichen und zurückgeben:
- < 0, wenn arg1 kleiner als arg2 ist
- 0, wenn arg1 gleich arg2 ist
- > 0, wenn arg1 größer als arg2 ist
*/
typedef int (*CompareFctType)(const void *arg1, const void *arg2);
/*
Struktur für einen Binärbaum-Knoten.
Enthält:
- data: Zeiger auf die gespeicherten Daten (beliebiger Typ, dynamisch allokiert)
- left: Zeiger auf linken Teilbaum
- right: Zeiger auf rechten Teilbaum
*/
typedef struct node
{
void *data;
struct node *left;
struct node *right;
void *data; // Zeiger auf die Nutzdaten
struct node *left; // Zeiger auf linken Kindknoten
struct node *right; // Zeiger auf rechten Kindknoten
} TreeNode;
// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
// if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added).
/*
Fügt eine Kopie der Daten in den Binärbaum ein.
Parameter:
root : Wurzel des (Teil-)Baums
data : Zeiger auf die einzufügenden Daten
dataSize : Größe der Daten in Bytes
compareFct : Vergleichsfunktion für die Ordnung
isDuplicate : Optionaler Zeiger:
- Wenn NULL: Duplikate sind erlaubt
- Wenn != NULL: Duplikate werden ignoriert und *isDuplicate wird gesetzt:
- 0: neuer Eintrag eingefügt
- 1: Duplikat erkannt, nicht eingefügt
Rückgabe:
Zeiger auf die (ggf. neue) Wurzel des Baums oder NULL bei Speicherfehler.
*/
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate);
// Iterates over the tree given by root. Follows the usage of strtok. If tree is NULL, the next entry of the last tree given is returned in ordering direction.
// Use your implementation of a stack to organize the iterator. Push the root node and all left nodes first. On returning the next element,
// push the top node and push all its left nodes.
/*
Iteriert über den Baum in Inorder-Reihenfolge.
Verhalten:
- Erster Aufruf mit root != NULL: Iterator initialisieren
- Folgeaufrufe mit root == NULL: nächstes Element zurückgeben
Rückgabe:
Zeiger auf die Daten des nächsten Knotens oder NULL, wenn Ende erreicht.
Hinweis:
Intern wird ein Stack verwendet. Nicht threadsicher.
*/
void *nextTreeData(TreeNode *root);
// Releases all memory resources (including data copies).
/*
Gibt den gesamten Baum frei (inklusive der gespeicherten Daten).
Nach dem Aufruf sind alle Zeiger ungültig.
*/
void clearTree(TreeNode *root);
// Returns the number of entries in the tree given by root.
/*
Liefert die Anzahl der Knoten im Baum.
Rückgabe:
Anzahl der Knoten (0 bei leerem Baum).
*/
unsigned int treeSize(const TreeNode *root);
#endif
#endif
BIN
View File
Binary file not shown.
Executable
BIN
View File
Binary file not shown.
Executable
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+10 -1
View File
@@ -1 +1,10 @@
player1;3999
Lena;19811
Lena;19702
player_name;9981
Lena;9980
Lena;9978
Lena;9978
Lena;9976
Lena;9975
Lena;9971
Lena;9965
BIN
View File
Binary file not shown.
+28 -4
View File
@@ -29,14 +29,38 @@ program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
doble : main.o $(program_obj_files)
$(CC) $(FLAGS) $^ -o doble
$(program_obj_filesobj_files): %.o: %.c
$(CC) -c $(FLAGS) $^ -o $@
# pattern rule to build .o from .c
%.o: %.c
$(CC) -c $(FLAGS) $< -o $@
# --------------------------
# Unit Tests
# --------------------------
unitTests:
echo "needs to be implemented"
unitTests: test_stack test_numbers test_bintree
@total=0; passed=0; failed=0; \
for t in test_stack test_numbers test_bintree; do \
total=$$((total+1)); \
printf "Running %s...\n" "$$t"; \
./$$t; rc=$$?; \
if [ $$rc -eq 0 ]; then \
printf "%s: PASS\n\n" "$$t"; \
passed=$$((passed+1)); \
else \
printf "%s: FAIL (exit %d)\n\n" "$$t" $$rc; \
failed=$$((failed+1)); \
fi; \
done; \
printf "Summary: %d tests run, %d passed, %d failed\n" $$total $$passed $$failed; \
exit $$failed
test_stack: test_stack.c stack.c
$(CC) $(FLAGS) test_stack.c stack.c -o test_stack
test_numbers: test_numbers.c numbers.c bintree.c stack.c
$(CC) $(FLAGS) test_numbers.c numbers.c bintree.c stack.c -o test_numbers
test_bintree: test_bintree.c bintree.c stack.c
$(CC) $(FLAGS) test_bintree.c bintree.c stack.c -o test_bintree
# --------------------------
# Clean
+90 -5
View File
@@ -5,22 +5,107 @@
#include "numbers.h"
#include "bintree.h"
//TODO: getDuplicate und createNumbers implementieren
/* * * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen.
* Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
* Duplizieren eines zufälligen Eintrags im Array.
* in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */
// helper comparator for unsigned int for bintree
static int compareUInt(const void *a, const void *b)
{
unsigned int va = *(const unsigned int *)a;
unsigned int vb = *(const unsigned int *)b;
if(va < vb) return -1;
if(va > vb) return 1;
return 0;
}
// comparator for qsort (unsigned int)
static int qsort_uint_cmp(const void *a, const void *b)
{
unsigned int va = *(const unsigned int *)a;
unsigned int vb = *(const unsigned int *)b;
if(va < vb) return -1;
if(va > vb) return 1;
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
// creating random numbers.
unsigned int *createNumbers(unsigned int len)
{
if(len < 2)
return NULL;
unsigned int *numbers = (unsigned int *)malloc(sizeof(unsigned int) * len);
if(numbers == NULL)
return NULL;
// seed once
srand((unsigned int)time(NULL));
TreeNode *root = NULL;
unsigned int range = 2 * len;
// create len-1 unique numbers
for(unsigned int i = 0; i < len - 1; i++)
{
unsigned int val;
int isDup = 0;
// try until a unique number is inserted
do
{
val = (unsigned int)(rand() % range) + 1; // [1..2*len]
root = addToTree(root, &val, sizeof(val), compareUInt, &isDup);
// if addToTree returned NULL due to allocation failure, cleanup and return NULL
if(root == NULL && isDup == 0)
{
free(numbers);
clearTree(root);
return NULL;
}
} while(isDup);
numbers[i] = val;
}
// duplicate one existing random entry
unsigned int idx = (unsigned int)(rand() % (len - 1));
numbers[len - 1] = numbers[idx];
// shuffle array (Fisher-Yates)
for(unsigned int i = len - 1; i > 0; i--)
{
unsigned int j = (unsigned int)(rand() % (i + 1));
unsigned int tmp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = tmp;
}
// free tree resources
clearTree(root);
return numbers;
}
// Returns only the only number in numbers which is present twice. Returns zero on errors.
unsigned int getDuplicate(const unsigned int numbers[], unsigned int len)
{
if(numbers == NULL || len < 2)
return 0;
// make a copy so original array order is not modified by caller expectation
unsigned int *copy = (unsigned int *)malloc(sizeof(unsigned int) * len);
if(copy == NULL)
return 0;
memcpy(copy, numbers, sizeof(unsigned int) * len);
qsort(copy, len, sizeof(unsigned int), qsort_uint_cmp);
unsigned int result = 0;
for(unsigned int i = 0; i + 1 < len; i++)
{
if(copy[i] == copy[i+1])
{
result = copy[i];
break;
}
}
free(copy);
return result;
}
BIN
View File
Binary file not shown.
+22 -8
View File
@@ -1,33 +1,47 @@
#include <stdlib.h>
#include "stack.h"
//TODO: grundlegende Stackfunktionen implementieren:
/* * `push`: legt ein Element oben auf den Stack,
* `pop`: entfernt das oberste Element,
* `top`: liefert das oberste Element zurück,
* `clearStack`: gibt den gesamten Speicher frei. */
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data)
{
StackNode *node = (StackNode *)malloc(sizeof(StackNode));
if(node == NULL)
return stack; // allocation failed -> return unchanged stack
node->data = data;
node->next = stack;
return node;
}
// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
// freed by caller.)
StackNode *pop(StackNode *stack)
{
if(stack == NULL)
return NULL;
StackNode *next = stack->next;
// Do NOT free stack->data here; caller owns the pointed data
free(stack);
return next;
}
// Returns the data of the top element.
void *top(StackNode *stack)
{
if(stack == NULL)
return NULL;
return stack->data;
}
// Clears stack and releases all memory.
void clearStack(StackNode *stack)
{
while(stack != NULL)
{
StackNode *next = stack->next;
// Do NOT free stack->data here; caller owns the pointed data
free(stack);
stack = next;
}
}
+6 -1
View File
@@ -7,7 +7,12 @@ The latest element is taken from the stack. */
#include <stdlib.h>
//TODO: passenden Datentyp als struct anlegen
// Stack node for linked-list based stack. Data pointer is stored but not freed by stack operations.
typedef struct StackNode
{
void *data;
struct StackNode *next;
} StackNode;
// Pushes data as pointer onto the stack.
StackNode *push(StackNode *stack, void *data);
BIN
View File
Binary file not shown.
Executable
BIN
View File
Binary file not shown.
+48
View File
@@ -0,0 +1,48 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bintree.h"
// comparator for unsigned int values stored by value in heap
static int cmp_uint_ptr(const void *a, const void *b)
{
unsigned int va = *(const unsigned int *)a;
unsigned int vb = *(const unsigned int *)b;
if(va < vb) return -1;
if(va > vb) return 1;
return 0;
}
int main(void)
{
TreeNode *root = NULL;
unsigned int vals[] = {5, 2, 8, 1, 3, 7, 9};
const size_t n = sizeof(vals)/sizeof(vals[0]);
// insert values (copy made by addToTree)
for(size_t i = 0; i < n; i++)
{
int isDup = 0;
root = addToTree(root, &vals[i], sizeof(unsigned int), cmp_uint_ptr, &isDup);
if(root == NULL && isDup == 0) { fprintf(stderr, "addToTree allocation failed\n"); return 1; }
}
unsigned int sz = treeSize(root);
if(sz != n) { fprintf(stderr, "treeSize expected %zu got %u\n", n, sz); clearTree(root); return 2; }
// inorder traversal using nextTreeData
unsigned int last = 0;
int first = 1;
unsigned int *data = nextTreeData(root);
while(data != NULL)
{
unsigned int v = *data;
if(!first && v < last) { fprintf(stderr, "inorder traversal not sorted: %u after %u\n", v, last); clearTree(root); return 3; }
last = v; first = 0;
data = nextTreeData(NULL);
}
clearTree(root);
printf("test_bintree: OK\n");
return 0;
}
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.test_bintree</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
@@ -0,0 +1,20 @@
---
triple: 'x86_64-apple-darwin'
binary-path: test_bintree
relocations:
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x1000007A0, symSize: 0x220 }
- { offset: 0x49, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x1000007A0, symSize: 0x220 }
- { offset: 0x121, size: 0x8, addend: 0x0, symName: _cmp_uint_ptr, symObjAddr: 0x220, symBinAddr: 0x1000009C0, symSize: 0x5A }
- { offset: 0x21B, size: 0x8, addend: 0x0, symName: _addToTree, symObjAddr: 0x0, symBinAddr: 0x100000A20, symSize: 0x1C0 }
- { offset: 0x228, size: 0x8, addend: 0x0, symName: _nextTreeData, symObjAddr: 0x1C0, symBinAddr: 0x100000BE0, symSize: 0xC0 }
- { offset: 0x24D, size: 0x8, addend: 0x0, symName: _nextTreeData.iterStack, symObjAddr: 0xFB0, symBinAddr: 0x100002000, symSize: 0x0 }
- { offset: 0x2EC, size: 0x8, addend: 0x0, symName: _addToTree, symObjAddr: 0x0, symBinAddr: 0x100000A20, symSize: 0x1C0 }
- { offset: 0x376, size: 0x8, addend: 0x0, symName: _bintree_pushLefts, symObjAddr: 0x280, symBinAddr: 0x100000CA0, symSize: 0x50 }
- { offset: 0x3A8, size: 0x8, addend: 0x0, symName: _clearTree, symObjAddr: 0x2D0, symBinAddr: 0x100000CF0, symSize: 0x60 }
- { offset: 0x3CC, size: 0x8, addend: 0x0, symName: _treeSize, symObjAddr: 0x330, symBinAddr: 0x100000D50, symSize: 0x56 }
- { offset: 0x47F, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100000DB0, symSize: 0x60 }
- { offset: 0x4C3, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100000DB0, symSize: 0x60 }
- { offset: 0x507, size: 0x8, addend: 0x0, symName: _pop, symObjAddr: 0x60, symBinAddr: 0x100000E10, symSize: 0x50 }
- { offset: 0x53D, size: 0x8, addend: 0x0, symName: _top, symObjAddr: 0xB0, symBinAddr: 0x100000E60, symSize: 0x40 }
- { offset: 0x565, size: 0x8, addend: 0x0, symName: _clearStack, symObjAddr: 0xF0, symBinAddr: 0x100000EA0, symSize: 0x3F }
...
Executable
BIN
View File
Binary file not shown.
+41
View File
@@ -0,0 +1,41 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "numbers.h"
int main(void)
{
unsigned int len = 100;
unsigned int *nums = createNumbers(len);
if(nums == NULL) { fprintf(stderr, "createNumbers returned NULL\n"); return 1; }
// count occurrences
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]]++;
}
int duplicatesFound = 0;
unsigned int duplicateValue = 0;
for(unsigned int v = 1; v <= maxVal; v++)
{
if(counts[v] == 2) { duplicatesFound++; duplicateValue = v; }
else if(counts[v] > 2) { fprintf(stderr, "value %u appears more than twice\n", v); free(nums); free(counts); return 4; }
}
if(duplicatesFound != 1) { fprintf(stderr, "expected exactly one duplicated value, found %d\n", duplicatesFound); free(nums); free(counts); return 5; }
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; }
free(nums);
free(counts);
printf("test_numbers: OK (duplicate = %u)\n", duplicateValue);
return 0;
}
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.test_numbers</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
@@ -0,0 +1,24 @@
---
triple: 'x86_64-apple-darwin'
binary-path: test_numbers
relocations:
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x1000013A0, symSize: 0x287 }
- { offset: 0x41, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x1000013A0, symSize: 0x287 }
- { offset: 0x12E, size: 0x8, addend: 0x0, symName: _createNumbers, symObjAddr: 0x0, symBinAddr: 0x100001630, symSize: 0x1D0 }
- { offset: 0x152, size: 0x8, addend: 0x0, symName: _createNumbers, symObjAddr: 0x0, symBinAddr: 0x100001630, symSize: 0x1D0 }
- { offset: 0x23E, size: 0x8, addend: 0x0, symName: _compareUInt, symObjAddr: 0x1D0, symBinAddr: 0x100001800, symSize: 0x60 }
- { offset: 0x290, size: 0x8, addend: 0x0, symName: _getDuplicate, symObjAddr: 0x230, symBinAddr: 0x100001860, symSize: 0x110 }
- { offset: 0x2FE, size: 0x8, addend: 0x0, symName: _qsort_uint_cmp, symObjAddr: 0x340, symBinAddr: 0x100001970, symSize: 0x5A }
- { offset: 0x3C5, size: 0x8, addend: 0x0, symName: _addToTree, symObjAddr: 0x0, symBinAddr: 0x1000019D0, symSize: 0x1C0 }
- { offset: 0x3D2, size: 0x8, addend: 0x0, symName: _nextTreeData, symObjAddr: 0x1C0, symBinAddr: 0x100001B90, symSize: 0xC0 }
- { offset: 0x3F7, size: 0x8, addend: 0x0, symName: _nextTreeData.iterStack, symObjAddr: 0xFB0, symBinAddr: 0x100003000, symSize: 0x0 }
- { offset: 0x496, size: 0x8, addend: 0x0, symName: _addToTree, symObjAddr: 0x0, symBinAddr: 0x1000019D0, symSize: 0x1C0 }
- { offset: 0x520, size: 0x8, addend: 0x0, symName: _bintree_pushLefts, symObjAddr: 0x280, symBinAddr: 0x100001C50, symSize: 0x50 }
- { offset: 0x552, size: 0x8, addend: 0x0, symName: _clearTree, symObjAddr: 0x2D0, symBinAddr: 0x100001CA0, symSize: 0x60 }
- { offset: 0x576, size: 0x8, addend: 0x0, symName: _treeSize, symObjAddr: 0x330, symBinAddr: 0x100001D00, symSize: 0x56 }
- { offset: 0x629, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100001D60, symSize: 0x60 }
- { offset: 0x66D, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100001D60, symSize: 0x60 }
- { offset: 0x6B1, size: 0x8, addend: 0x0, symName: _pop, symObjAddr: 0x60, symBinAddr: 0x100001DC0, symSize: 0x50 }
- { offset: 0x6E7, size: 0x8, addend: 0x0, symName: _top, symObjAddr: 0xB0, symBinAddr: 0x100001E10, symSize: 0x40 }
- { offset: 0x70F, size: 0x8, addend: 0x0, symName: _clearStack, symObjAddr: 0xF0, symBinAddr: 0x100001E50, symSize: 0x3F }
...
Executable
BIN
View File
Binary file not shown.
+44
View File
@@ -0,0 +1,44 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "stack.h"
int main(void)
{
StackNode *s = NULL;
// push 3 integers
int *a = malloc(sizeof(int)); *a = 1; 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)
int *topv = (int *)top(s);
if(topv == NULL || *topv != 3) { fprintf(stderr, "stack top expected 3\n"); return 1; }
// pop -> now top should be 2
s = pop(s);
topv = (int *)top(s);
if(topv == NULL || *topv != 2) { fprintf(stderr, "stack top expected 2 after pop\n"); return 2; }
// pop -> now top should be 1
s = pop(s);
topv = (int *)top(s);
if(topv == NULL || *topv != 1) { fprintf(stderr, "stack top expected 1 after pop\n"); return 3; }
// pop last
s = pop(s);
if(s != NULL) { fprintf(stderr, "stack expected empty after popping all\n"); return 4; }
// free stored data (stack does not free data)
free(a); free(b); free(c);
// test clearStack on empty and small stacks
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
// Note: above payloads are not freed (stack API spec); this test ensures clearStack doesn't crash.
// Success
printf("test_stack: OK\n");
return 0;
}
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.test_stack</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
Binary file not shown.
@@ -0,0 +1,12 @@
---
triple: 'x86_64-apple-darwin'
binary-path: test_stack
relocations:
- { offset: 0x26, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x100000B80, symSize: 0x249 }
- { offset: 0x4E, size: 0x8, addend: 0x0, symName: _main, symObjAddr: 0x0, symBinAddr: 0x100000B80, symSize: 0x249 }
- { offset: 0x10A, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100000DD0, symSize: 0x60 }
- { offset: 0x14E, size: 0x8, addend: 0x0, symName: _push, symObjAddr: 0x0, symBinAddr: 0x100000DD0, symSize: 0x60 }
- { offset: 0x192, size: 0x8, addend: 0x0, symName: _pop, symObjAddr: 0x60, symBinAddr: 0x100000E30, symSize: 0x50 }
- { offset: 0x1C8, size: 0x8, addend: 0x0, symName: _top, symObjAddr: 0xB0, symBinAddr: 0x100000E80, symSize: 0x40 }
- { offset: 0x1F0, size: 0x8, addend: 0x0, symName: _clearStack, symObjAddr: 0xF0, symBinAddr: 0x100000EC0, symSize: 0x3F }
...
BIN
View File
Binary file not shown.