From 381875245ee2293a14e090aa1e28deedfb6733f1 Mon Sep 17 00:00:00 2001 From: Kola Date: Wed, 11 Dec 2024 19:56:53 +0300 Subject: [PATCH] add lr --- 05_hw/CMakeLists.txt | 13 ++- 05_hw/benchmark_stack.c | 43 ++++++++ 05_hw/main.c | 15 ++- 05_hw/stack.c | 46 +++++++-- 05_hw/test_stack.c | 218 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 322 insertions(+), 13 deletions(-) create mode 100644 05_hw/benchmark_stack.c create mode 100644 05_hw/test_stack.c diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 6f5e398..a4e72b9 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -1,7 +1,16 @@ cmake_minimum_required(VERSION 3.10) project(stack) +set(CMAKE_C_STANDARD 99) + add_library(stack stack.c) -add_executable(main main.c) -target_link_libraries(main stack) +add_executable(test_stack test_stack.c) + +target_link_libraries(test_stack stack) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + +add_executable(benchmark_stack benchmark_stack.c stack.c) + diff --git a/05_hw/benchmark_stack.c b/05_hw/benchmark_stack.c new file mode 100644 index 0000000..04dc4bf --- /dev/null +++ b/05_hw/benchmark_stack.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include "stack.h" + +#define NUM_ITERATIONS 1000000 + +void benchmark_push(Stack* stack) { + clock_t start = clock(); + for (int i = 0; i < NUM_ITERATIONS; i++) { + push(stack, i); + } + clock_t end = clock(); + double elapsed_time = (double)(end - start) / CLOCKS_PER_SEC; + printf("Push benchmark: %d iterations took %.5f seconds.\n", NUM_ITERATIONS, elapsed_time); +} + +void benchmark_pop(Stack* stack) { + clock_t start = clock(); + for (int i = 0; i < NUM_ITERATIONS; i++) { + pop(stack); + } + clock_t end = clock(); + double elapsed_time = (double)(end - start) / CLOCKS_PER_SEC; + printf("Pop benchmark: %d iterations took %.5f seconds.\n", NUM_ITERATIONS, elapsed_time); +} + +int main() { + Stack stack; + initStack(&stack); + + benchmark_push(&stack); + + for (int i = 0; i < NUM_ITERATIONS; i++) { + push(&stack, i); + } + + benchmark_pop(&stack); + + destroyStack(&stack); + + return 0; +} diff --git a/05_hw/main.c b/05_hw/main.c index fded814..603da4a 100644 --- a/05_hw/main.c +++ b/05_hw/main.c @@ -1,6 +1,5 @@ #include "stack.h" - -#include +#include "stdio.h" int main() { Stack stack; @@ -10,6 +9,7 @@ int main() { push(&stack, 20); push(&stack, 30); + printf("After pushing elements:\n"); traverseStack(&stack); @@ -21,7 +21,8 @@ int main() { Node* searchResult = searchByValue(&stack, 20); if (searchResult != NULL) { printf("Element with value 20 found.\n"); - } else { + } + else { printf("Element with value 20 not found.\n"); } @@ -29,8 +30,12 @@ int main() { if (topElement != NULL) { printf("Top element: %d\n", topElement->data); } + else { + printf("Stack is empty.\n"); + } + + destroyStack(&stack); + printf("Stack destroyed.\n"); return 0; } - - diff --git a/05_hw/stack.c b/05_hw/stack.c index 0964440..37273c6 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -1,50 +1,79 @@ #include #include - #include "stack.h" Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); + if (newNode == NULL) { + fprintf(stderr, "Memory allocation failed\n"); + return NULL; + } newNode->data = data; newNode->next = NULL; return newNode; } void initStack(Stack* stack) { + if (stack == NULL) { + fprintf(stderr, "Stack initialization failed: NULL pointer\n"); + return; + } stack->top = NULL; } void destroyStack(Stack* stack) { + if (stack == NULL) { + return; + } Node* current = stack->top; while (current != NULL) { - Node *tmp = current; + Node* tmp = current; current = current->next; - free(tmp); + free(tmp); } + stack->top = NULL; } void push(Stack* stack, int data) { + if (stack == NULL) { + fprintf(stderr, "Push failed: NULL stack pointer\n"); + return; + } Node* newNode = createNode(data); + if (newNode == NULL) { + return; + } newNode->next = stack->top; stack->top = newNode; } void pop(Stack* stack) { + if (stack == NULL || stack->top == NULL) { + return; + } Node* temp = stack->top; stack->top = stack->top->next; + free(temp); } Node* searchByValue(Stack* stack, int value) { + if (stack == NULL) { + return NULL; + } Node* current = stack->top; while (current != NULL) { if (current->data == value) { return current; } + current = current->next; } return NULL; } Node* searchByIndex(Stack* stack, int index) { + if (stack == NULL) { + return NULL; + } Node* current = stack->top; int count = 0; while (current != NULL) { @@ -58,10 +87,17 @@ Node* searchByIndex(Stack* stack, int index) { } Node* getTop(Stack* stack) { + if (stack == NULL || stack->top == NULL) { + return NULL; + } return stack->top; } void traverseStack(Stack* stack) { + if (stack == NULL) { + printf("Stack is not initialized.\n"); + return; + } Node* current = stack->top; printf("Stack elements: "); while (current != NULL) { @@ -72,7 +108,5 @@ void traverseStack(Stack* stack) { } bool isEmpty(Stack* stack) { - free(stack->top); - return stack->top == NULL; + return stack == NULL || stack->top == NULL; } - diff --git a/05_hw/test_stack.c b/05_hw/test_stack.c new file mode 100644 index 0000000..b8c4aad --- /dev/null +++ b/05_hw/test_stack.c @@ -0,0 +1,218 @@ +#include "stack.h" +#include +#include + +void test_push_null_stack() { + push(NULL, 10); + printf("Test: push with NULL stack - PASSED\n"); +} + +void test_pop_null_stack() { + pop(NULL); + printf("Test: pop with NULL stack - PASSED\n"); +} + +void test_destroyStack_null_stack() { + destroyStack(NULL); + printf("Test: destroyStack with NULL stack - PASSED\n"); +} + +void test_initStack_null() { + initStack(NULL); + printf("Test: initStack with NULL - PASSED\n"); +} + +void test_destroyStack_non_empty() { + Stack stack; + initStack(&stack); + + push(&stack, 10); + push(&stack, 20); + push(&stack, 30); + + destroyStack(&stack); + assert(stack.top == NULL); + + printf("Test: destroyStack on non-empty stack - PASSED\n"); +} + +void test_getTop_non_empty_stack() { + Stack stack; + initStack(&stack); + + push(&stack, 10); + push(&stack, 20); + + Node* top = getTop(&stack); + assert(top != NULL && top->data == 20); + + printf("Test: getTop on non-empty stack - PASSED\n"); +} + +void test_getTop_empty_stack() { + Stack stack; + initStack(&stack); + + Node* top = getTop(&stack); + assert(top == NULL); + + printf("Test: getTop on empty stack - PASSED\n"); +} + +void test_traverseStack_empty() { + Stack stack; + initStack(&stack); + + printf("Expected output: (nothing)\n"); + printf("Actual output: "); + traverseStack(&stack); + + printf("Test: traverseStack on empty stack - PASSED\n"); +} + +void test_traverseStack_non_empty() { + Stack stack; + initStack(&stack); + + push(&stack, 10); + push(&stack, 20); + push(&stack, 30); + + printf("Expected output: Stack elements: 30 20 10\n"); + printf("Actual output: "); + traverseStack(&stack); + + printf("Test: traverseStack on non-empty stack - PASSED\n"); +} + +void test_searchByIndex() { + Stack stack; + initStack(&stack); + + push(&stack, 10); + push(&stack, 20); + push(&stack, 30); + + Node* result = searchByIndex(&stack, 1); + assert(result != NULL && result->data == 20); + + result = searchByIndex(&stack, 5); + assert(result == NULL); + + printf("Test: searchByIndex - PASSED\n"); +} + +void test_isEmpty() { + Stack stack; + initStack(&stack); + + assert(isEmpty(&stack) == true); + + push(&stack, 10); + assert(isEmpty(&stack) == false); + + pop(&stack); + assert(isEmpty(&stack) == true); + + printf("Test: isEmpty - PASSED\n"); +} + +void test_searchByValue_null_stack() { + Node* result = searchByValue(NULL, 10); + assert(result == NULL); + printf("Test: searchByValue with NULL stack - PASSED\n"); +} + +void test_searchByValue_empty_stack() { + Stack stack; + initStack(&stack); + + Node* result = searchByValue(&stack, 10); + assert(result == NULL); + printf("Test: searchByValue on empty stack - PASSED\n"); +} + +void test_searchByValue_existing_value() { + Stack stack; + initStack(&stack); + + push(&stack, 10); + push(&stack, 20); + push(&stack, 30); + + Node* result = searchByValue(&stack, 20); + assert(result != NULL && result->data == 20); + printf("Test: searchByValue with existing value - PASSED\n"); +} + +void test_searchByValue_non_existing_value() { + Stack stack; + initStack(&stack); + + push(&stack, 10); + push(&stack, 20); + push(&stack, 30); + + Node* result = searchByValue(&stack, 40); + assert(result == NULL); + printf("Test: searchByValue with non-existing value - PASSED\n"); +} + + +void test_createNode_null() { + Node* node = createNode(10); + assert(node != NULL); + printf("Test: createNode handles memory allocation successfully - PASSED\n"); +} + +void test_push_memory_failure() { + Stack stack; + initStack(&stack); + + push(&stack, 10); + assert(stack.top != NULL); + printf("Test: push handles memory allocation successfully - PASSED\n"); +} + + +void test_searchByIndex_null_stack() { + Node* result = searchByIndex(NULL, 0); + assert(result == NULL); + printf("Test: searchByIndex with NULL stack - PASSED\n"); +} + + +void test_traverseStack_null_stack() { + traverseStack(NULL); + printf("Test: traverseStack with NULL stack - PASSED\n"); +} + +int main() { + + test_push_null_stack(); + test_pop_null_stack(); + test_destroyStack_null_stack(); + test_initStack_null(); + + test_destroyStack_non_empty(); + test_getTop_non_empty_stack(); + test_getTop_empty_stack(); + test_traverseStack_empty(); + test_traverseStack_non_empty(); + test_searchByIndex(); + test_isEmpty(); + + test_searchByValue_null_stack(); + test_searchByValue_empty_stack(); + test_searchByValue_existing_value(); + test_searchByValue_non_existing_value(); + + test_createNode_null(); + test_push_memory_failure(); + + test_searchByIndex_null_stack(); + test_traverseStack_null_stack(); + + printf("All tests passed successfully!\n"); + return 0; +}