Compare commits
No commits in common. "0d8a30374257f68cee3e0b88d8eeb3750cfe6381" and "ef14e5465ca28adc5c96660f3c4312d0f2488243" have entirely different histories.
0d8a303742
...
ef14e5465c
87
bintree.c
87
bintree.c
@ -1,65 +1,18 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "stack.h"
|
#include "stack.h"
|
||||||
#include "bintree.h"
|
#include "bintree.h"
|
||||||
|
|
||||||
// internal helper to push node and all its left descendants onto iterator stack
|
//TODO: binären Suchbaum implementieren
|
||||||
static void bintree_pushLefts(StackNode **iterStackPtr, TreeNode *n)
|
/* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv),
|
||||||
{
|
* `clearTree`: gibt den gesamten Baum frei (rekursiv),
|
||||||
while(n != NULL)
|
* `treeSize`: zählt die Knoten im Baum (rekursiv),
|
||||||
{
|
* `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */
|
||||||
*iterStackPtr = push(*iterStackPtr, n);
|
|
||||||
n = n->left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates
|
// 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).
|
// 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)
|
TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate)
|
||||||
{
|
{
|
||||||
if(isDuplicate != NULL)
|
|
||||||
*isDuplicate = 0;
|
|
||||||
|
|
||||||
if(root == NULL)
|
|
||||||
{
|
|
||||||
TreeNode *node = (TreeNode *)malloc(sizeof(TreeNode));
|
|
||||||
if(node == NULL)
|
|
||||||
return NULL;
|
|
||||||
node->data = malloc(dataSize);
|
|
||||||
if(node->data == NULL)
|
|
||||||
{
|
|
||||||
free(node);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
memcpy(node->data, data, dataSize);
|
|
||||||
node->left = node->right = NULL;
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cmp = compareFct(data, root->data);
|
|
||||||
if(cmp < 0)
|
|
||||||
{
|
|
||||||
root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate);
|
|
||||||
}
|
|
||||||
else if(cmp > 0)
|
|
||||||
{
|
|
||||||
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
|
|
||||||
}
|
|
||||||
else // equal
|
|
||||||
{
|
|
||||||
if(isDuplicate != NULL)
|
|
||||||
{
|
|
||||||
*isDuplicate = 1;
|
|
||||||
// do not insert duplicate
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// duplicates allowed -> insert into right subtree
|
|
||||||
root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return root;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.
|
// 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.
|
||||||
@ -67,45 +20,17 @@ TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFc
|
|||||||
// push the top node and push all its left nodes.
|
// push the top node and push all its left nodes.
|
||||||
void *nextTreeData(TreeNode *root)
|
void *nextTreeData(TreeNode *root)
|
||||||
{
|
{
|
||||||
static StackNode *iterStack = NULL;
|
|
||||||
|
|
||||||
// If a new tree root is provided -> reset iterator
|
|
||||||
if(root != NULL)
|
|
||||||
{
|
|
||||||
clearStack(iterStack);
|
|
||||||
iterStack = NULL;
|
|
||||||
bintree_pushLefts(&iterStack, root);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(iterStack == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
TreeNode *node = (TreeNode *)top(iterStack);
|
|
||||||
iterStack = pop(iterStack);
|
|
||||||
|
|
||||||
if(node->right != NULL)
|
|
||||||
bintree_pushLefts(&iterStack, node->right);
|
|
||||||
|
|
||||||
return node->data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Releases all memory resources (including data copies).
|
// Releases all memory resources (including data copies).
|
||||||
void clearTree(TreeNode *root)
|
void clearTree(TreeNode *root)
|
||||||
{
|
{
|
||||||
if(root == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
clearTree(root->left);
|
|
||||||
clearTree(root->right);
|
|
||||||
|
|
||||||
free(root->data);
|
|
||||||
free(root);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the number of entries in the tree given by root.
|
// Returns the number of entries in the tree given by root.
|
||||||
unsigned int treeSize(const TreeNode *root)
|
unsigned int treeSize(const TreeNode *root)
|
||||||
{
|
{
|
||||||
if(root == NULL)
|
|
||||||
return 0;
|
|
||||||
return 1 + treeSize(root->left) + treeSize(root->right);
|
|
||||||
}
|
}
|
||||||
BIN
doble_initial
BIN
doble_initial
Binary file not shown.
BIN
highscore.o
BIN
highscore.o
Binary file not shown.
@ -1,10 +1 @@
|
|||||||
Lena;19811
|
player1;3999
|
||||||
Lena;19702
|
|
||||||
player_name;9981
|
|
||||||
Lena;9980
|
|
||||||
Lena;9978
|
|
||||||
Lena;9978
|
|
||||||
Lena;9976
|
|
||||||
Lena;9975
|
|
||||||
Lena;9971
|
|
||||||
Lena;9965
|
|
||||||
|
|||||||
32
makefile
32
makefile
@ -29,38 +29,14 @@ program_obj_files = stack.o bintree.o numbers.o timer.o highscore.o
|
|||||||
doble : main.o $(program_obj_files)
|
doble : main.o $(program_obj_files)
|
||||||
$(CC) $(FLAGS) $^ -o doble
|
$(CC) $(FLAGS) $^ -o doble
|
||||||
|
|
||||||
# pattern rule to build .o from .c
|
$(program_obj_filesobj_files): %.o: %.c
|
||||||
%.o: %.c
|
$(CC) -c $(FLAGS) $^ -o $@
|
||||||
$(CC) -c $(FLAGS) $< -o $@
|
|
||||||
|
|
||||||
# --------------------------
|
# --------------------------
|
||||||
# Unit Tests
|
# Unit Tests
|
||||||
# --------------------------
|
# --------------------------
|
||||||
unitTests: test_stack test_numbers test_bintree
|
unitTests:
|
||||||
@total=0; passed=0; failed=0; \
|
echo "needs to be implemented"
|
||||||
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
|
# Clean
|
||||||
|
|||||||
95
numbers.c
95
numbers.c
@ -5,107 +5,22 @@
|
|||||||
#include "numbers.h"
|
#include "numbers.h"
|
||||||
#include "bintree.h"
|
#include "bintree.h"
|
||||||
|
|
||||||
// helper comparator for unsigned int for bintree
|
//TODO: getDuplicate und createNumbers implementieren
|
||||||
static int compareUInt(const void *a, const void *b)
|
/* * * Erzeugen eines Arrays mit der vom Nutzer eingegebenen Anzahl an Zufallszahlen.
|
||||||
{
|
* Sicherstellen, dass beim Befüllen keine Duplikate entstehen.
|
||||||
unsigned int va = *(const unsigned int *)a;
|
* Duplizieren eines zufälligen Eintrags im Array.
|
||||||
unsigned int vb = *(const unsigned int *)b;
|
* in `getDuplicate()`: Sortieren des Arrays und Erkennen der doppelten Zahl durch Vergleich benachbarter Elemente. */
|
||||||
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 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
|
// Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while
|
||||||
// creating random numbers.
|
// creating random numbers.
|
||||||
unsigned int *createNumbers(unsigned int len)
|
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.
|
// 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)
|
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;
|
|
||||||
}
|
}
|
||||||
30
stack.c
30
stack.c
@ -1,47 +1,33 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "stack.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.
|
// Pushes data as pointer onto the stack.
|
||||||
StackNode *push(StackNode *stack, void *data)
|
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
|
// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be
|
||||||
// freed by caller.)
|
// freed by caller.)
|
||||||
StackNode *pop(StackNode *stack)
|
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.
|
// Returns the data of the top element.
|
||||||
void *top(StackNode *stack)
|
void *top(StackNode *stack)
|
||||||
{
|
{
|
||||||
if(stack == NULL)
|
|
||||||
return NULL;
|
|
||||||
return stack->data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clears stack and releases all memory.
|
// Clears stack and releases all memory.
|
||||||
void clearStack(StackNode *stack)
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
7
stack.h
7
stack.h
@ -7,12 +7,7 @@ The latest element is taken from the stack. */
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
// Stack node for linked-list based stack. Data pointer is stored but not freed by stack operations.
|
//TODO: passenden Datentyp als struct anlegen
|
||||||
typedef struct StackNode
|
|
||||||
{
|
|
||||||
void *data;
|
|
||||||
struct StackNode *next;
|
|
||||||
} StackNode;
|
|
||||||
|
|
||||||
// Pushes data as pointer onto the stack.
|
// Pushes data as pointer onto the stack.
|
||||||
StackNode *push(StackNode *stack, void *data);
|
StackNode *push(StackNode *stack, void *data);
|
||||||
|
|||||||
BIN
test_bintree
BIN
test_bintree
Binary file not shown.
@ -1,48 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
<?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>
|
|
||||||
Binary file not shown.
@ -1,20 +0,0 @@
|
|||||||
---
|
|
||||||
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 }
|
|
||||||
...
|
|
||||||
BIN
test_numbers
BIN
test_numbers
Binary file not shown.
@ -1,41 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
<?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>
|
|
||||||
Binary file not shown.
@ -1,24 +0,0 @@
|
|||||||
---
|
|
||||||
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 }
|
|
||||||
...
|
|
||||||
BIN
test_stack
BIN
test_stack
Binary file not shown.
44
test_stack.c
44
test_stack.c
@ -1,44 +0,0 @@
|
|||||||
#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;
|
|
||||||
}
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
<?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.
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
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 }
|
|
||||||
...
|
|
||||||
Loading…
x
Reference in New Issue
Block a user