From c5cf3af75b8be1b7862695823afdce6f2866de92 Mon Sep 17 00:00:00 2001 From: Dan Losev Date: Tue, 24 Dec 2024 12:54:11 +0300 Subject: [PATCH 1/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c95542c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +./.idea +./05_hw/.idea +./05_hw/cmake-build-debug \ No newline at end of file From 7abd91777fc0afe8f82b3fae2cc0de062af52935 Mon Sep 17 00:00:00 2001 From: Dan Losev Date: Tue, 24 Dec 2024 12:57:16 +0300 Subject: [PATCH 2/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2=D0=BE=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BA=D1=80=D1=8B=D1=82=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D0=B2=D1=8B=D1=8F=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 05_hw/CMakeLists.txt | 7 +- 05_hw/test_stack.c | 237 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 05_hw/test_stack.c diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 6f5e398..c574d5a 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -1,7 +1,12 @@ cmake_minimum_required(VERSION 3.10) project(stack) -add_library(stack stack.c) +set(CMAKE_C_STANDARD 99) + +add_library(stack STATIC stack.c) add_executable(main main.c) target_link_libraries(main stack) + +add_executable(test_stack test_stack.c stack.c) +target_link_libraries(test_stack stack) \ No newline at end of file diff --git a/05_hw/test_stack.c b/05_hw/test_stack.c new file mode 100644 index 0000000..fcdbe80 --- /dev/null +++ b/05_hw/test_stack.c @@ -0,0 +1,237 @@ +#include +#include +#include "stack.h" + +#define ASSERT(condition, message) \ + if (!(condition)) { \ + fprintf(stderr, "Assertion failed: %s\nFile: %s\nFunction: %s\nLine: %d\n", \ + message, __FILE__, __func__, __LINE__); \ + exit(EXIT_FAILURE); \ + } + +int all_tests = 0; +int passed_tests = 0; + +void test_initStack() { + printf("Running test_initStack...\n"); + all_tests++; + Stack stack; + initStack(&stack); + ASSERT(stack.top == NULL, "[TEST FAILED] - Stack initialization failed"); + passed_tests++; + printf("[TEST PASSED] - test_initStack.\n"); +} + +void test_push() { + printf("Running test_push...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + push(&stack, 10); + ASSERT(stack.top != NULL, "[TEST FAILED] - Push failed: stack.top is NULL"); + ASSERT(stack.top->data == 10, "[TEST FAILED] - Push failed: top data is not 10"); + passed_tests++; + printf("[TEST PASSED] - test_push.\n"); +} + +void test_pop() { + printf("Running test_pop...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + push(&stack, 20); + push(&stack, 30); + pop(&stack); + ASSERT(stack.top->data == 20, "[TEST FAILED] - Pop failed: top data is not 20"); + + pop(&stack); + ASSERT(stack.top == NULL, "[TEST FAILED] - Pop failed: stack is not empty"); + passed_tests++; + printf("[TEST PASSED] - test_pop passed.\n"); +} + +void test_searchByValue() { + printf("Running test_searchByValue...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + push(&stack, 40); + push(&stack, 50); + push(&stack, 60); + + Node* result = searchByValue(&stack, 50); + ASSERT(result != NULL && result->data == 50, "[TEST FAILED] - SearchByValue failed: value 50 not found"); + + result = searchByValue(&stack, 100); + ASSERT(result == NULL, "[TEST FAILED] - SearchByValue failed: non-existent value found"); + passed_tests++; + printf("[TEST PASSED] - test_searchByValue passed.\n"); +} + +void test_searchByIndex() { + printf("Running test_searchByIndex...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + push(&stack, 70); + push(&stack, 80); + push(&stack, 90); + + Node* result = searchByIndex(&stack, 1); + ASSERT(result != NULL && result->data == 80, "[TEST FAILED] - SearchByIndex failed: index 1 data mismatch"); + + result = searchByIndex(&stack, 5); + ASSERT(result == NULL, "[TEST FAILED] - SearchByIndex failed: non-existent index found"); + passed_tests++; + printf("[TEST PASSED] - test_searchByIndex passed.\n"); +} + +void test_destroyStack() { + printf("Running test_destroyStack...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + push(&stack, 100); + push(&stack, 200); + + destroyStack(&stack); + ASSERT(stack.top == NULL, "[TEST FAILED] - DestroyStack failed: stack is not empty"); + passed_tests++; + printf("[TEST PASSED] - test_destroyStack passed.\n"); +} + +void test_isEmpty() { + printf("Running test_isEmpty...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + ASSERT(isEmpty(&stack), "[TEST FAILED] - isEmpty failed: stack should be empty"); + push(&stack, 300); + ASSERT(!isEmpty(&stack), "[TEST FAILED] - isEmpty failed: stack should not be empty"); + passed_tests++; + printf("[TEST PASSED] - test_isEmpty passed.\n"); +} + +void test_getTop() { + printf("Running test_getTop...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + ASSERT(getTop(&stack) == NULL, "[TEST FAILED] - getTop failed: top should be NULL"); + push(&stack, 400); + ASSERT(getTop(&stack)->data == 400, "[TEST FAILED] - getTop failed: top data is not 400"); + passed_tests++; + printf("[TEST PASSED] - test_getTop passed.\n"); +} + +void test_push_multiple() { + printf("Running test_push_multiple...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + for (int i = 0; i < 1000; i++) { + push(&stack, i); + } + ASSERT(stack.top->data == 999, "[TEST FAILED] - Push multiple failed: top data is not 999"); + passed_tests++; + printf("[TEST PASSED] - test_push_multiple passed.\n"); +} + +void test_pop_all() { + printf("Running test_pop_all...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + for (int i = 0; i < 100; i++) { + push(&stack, i); + } + for (int i = 0; i < 100; i++) { + pop(&stack); + } + ASSERT(stack.top == NULL, "[TEST FAILED] - Pop all failed: stack is not empty"); + passed_tests++; + printf("[TEST PASSED] - test_pop_all passed.\n"); +} + +void test_memory_leak_destroy() { + printf("Running test_memory_leak_destroy...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + for (int i = 0; i < 500; i++) { + push(&stack, i); + } + destroyStack(&stack); + ASSERT(stack.top == NULL, "[TEST FAILED] - Memory leak destroy failed: stack is not empty"); + passed_tests++; + printf("[TEST PASSED] - test_memory_leak_destroy passed.\n"); +} + +void test_null_handling() { + printf("Running test_null_handling...\n"); + all_tests++; + Stack* nullStack = NULL; + ASSERT(nullStack == NULL, "[TEST FAILED] - Null handling failed: stack should be NULL"); + passed_tests++; + printf("[TEST PASSED] - test_null_handling passed.\n"); +} + +void test_single_element() { + printf("Running test_single_element...\n"); + all_tests++; + Stack stack; + initStack(&stack); + push(&stack, 1); + ASSERT(getTop(&stack)->data == 1, "[TEST FAILED] - Single element test failed: top data mismatch"); + pop(&stack); + ASSERT(stack.top == NULL, "[TEST FAILED] - Single element test failed: stack is not empty"); + passed_tests++; + printf("[TEST PASSED] - test_single_element passed.\n"); +} + +void test_large_stack_operations() { + printf("Running test_large_stack_operations...\n"); + all_tests++; + Stack stack; + initStack(&stack); + + for (int i = 0; i < 1000000; i++) { + push(&stack, i); + } + for (int i = 0; i < 1000000; i++) { + pop(&stack); + } + ASSERT(stack.top == NULL, "[TEST FAILED] - Large stack operations failed: stack is not empty"); + passed_tests++; + printf("[TEST PASSED] - test_large_stack_operations passed.\n"); +} + +int main() { + test_initStack(); + test_push(); + test_pop(); + //test_searchByValue(); + test_searchByIndex(); + // test_destroyStack(); + test_isEmpty(); + test_getTop(); + test_push_multiple(); + test_pop_all(); + // test_memory_leak_destroy(); + test_null_handling(); + test_single_element(); + test_large_stack_operations(); + + printf("\nSummary: %d/%d tests passed.\n", all_tests, passed_tests); + return (all_tests == passed_tests) ? EXIT_SUCCESS : EXIT_FAILURE; +} \ No newline at end of file From c541c11f31d074be185bfd3320a81055a71708b3 Mon Sep 17 00:00:00 2001 From: Dan Losev Date: Tue, 24 Dec 2024 19:37:00 +0300 Subject: [PATCH 3/6] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B8=20=D0=B2=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=B4=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 05_hw/main.c | 3 +++ 05_hw/stack.c | 14 +++++++++++--- 05_hw/test_stack.c | 6 +++--- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/05_hw/main.c b/05_hw/main.c index fded814..64d901a 100644 --- a/05_hw/main.c +++ b/05_hw/main.c @@ -30,6 +30,9 @@ int main() { printf("Top element: %d\n", topElement->data); } + destroyStack(&stack); + printf("Stack destroyed successfully.\n"); + return 0; } diff --git a/05_hw/stack.c b/05_hw/stack.c index 0964440..4865832 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -17,10 +17,11 @@ void initStack(Stack* stack) { void destroyStack(Stack* stack) { 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) { @@ -30,8 +31,12 @@ void push(Stack* stack, int data) { } void pop(Stack* stack) { + if (stack->top == NULL) { + return; + } Node* temp = stack->top; stack->top = stack->top->next; + free(temp); } Node* searchByValue(Stack* stack, int value) { @@ -40,6 +45,7 @@ Node* searchByValue(Stack* stack, int value) { if (current->data == value) { return current; } + current = current->next; } return NULL; } @@ -58,6 +64,9 @@ Node* searchByIndex(Stack* stack, int index) { } Node* getTop(Stack* stack) { + if (stack->top == NULL) { + return NULL; + } return stack->top; } @@ -72,7 +81,6 @@ void traverseStack(Stack* stack) { } bool isEmpty(Stack* stack) { - free(stack->top); return stack->top == NULL; } diff --git a/05_hw/test_stack.c b/05_hw/test_stack.c index fcdbe80..253e55d 100644 --- a/05_hw/test_stack.c +++ b/05_hw/test_stack.c @@ -220,14 +220,14 @@ int main() { test_initStack(); test_push(); test_pop(); - //test_searchByValue(); + test_searchByValue(); test_searchByIndex(); - // test_destroyStack(); + test_destroyStack(); test_isEmpty(); test_getTop(); test_push_multiple(); test_pop_all(); - // test_memory_leak_destroy(); + test_memory_leak_destroy(); test_null_handling(); test_single_element(); test_large_stack_operations(); From a46d65e34ef4ab5c7ae1694a7c9bdc3a4eeb4e06 Mon Sep 17 00:00:00 2001 From: Dan Losev Date: Tue, 24 Dec 2024 20:50:07 +0300 Subject: [PATCH 4/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D1=84=D0=BB=D0=B0=D0=B3=D0=B8=20=D0=B4=D0=BB=D1=8F=20=D0=B0?= =?UTF-8?q?=D0=BD=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=20=D0=BF=D0=BE=D0=BA=D1=80?= =?UTF-8?q?=D1=8B=D1=82=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=B4=D0=B0=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 05_hw/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index c574d5a..191cf3c 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -5,6 +5,9 @@ set(CMAKE_C_STANDARD 99) add_library(stack STATIC stack.c) +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + add_executable(main main.c) target_link_libraries(main stack) From 6f739f2d446bd7bd4fadb46a39b3474307f0d62b Mon Sep 17 00:00:00 2001 From: Dan Losev Date: Tue, 24 Dec 2024 20:50:27 +0300 Subject: [PATCH 5/6] =?UTF-8?q?=D0=A1=D0=B4=D0=B5=D0=BB=D0=B0=D0=BB=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=BD=D0=B0=20=D0=BE?= =?UTF-8?q?=D1=81=D0=BD=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B8=20=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=B1=D0=BE=D0=BA=20=D0=B0=D0=BD=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=82=D0=BE=D1=80=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 05_hw/stack.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/05_hw/stack.c b/05_hw/stack.c index 4865832..1be0eda 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -5,6 +5,10 @@ Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); + if (newNode == NULL) { + fprintf(stderr, "Memory allocation failed in createNode\n"); + exit(EXIT_FAILURE); + } newNode->data = data; newNode->next = NULL; return newNode; From ac18f2e9fee18e8c66939fbe9cd392f2103573ae Mon Sep 17 00:00:00 2001 From: Dan Losev Date: Wed, 25 Dec 2024 00:13:41 +0300 Subject: [PATCH 6/6] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB?= =?UTF-8?q?=20=D0=B1=D0=B5=D0=BD=D1=87=D0=BC=D0=B0=D1=80=D0=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 05_hw/CMakeLists.txt | 12 +++++------ 05_hw/benchmark_stack.c | 47 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 05_hw/benchmark_stack.c diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 191cf3c..5e63735 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -3,13 +3,13 @@ project(stack) set(CMAKE_C_STANDARD 99) -add_library(stack STATIC stack.c) +add_library(stack stack.c) + +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(main main.c) -target_link_libraries(main stack) - -add_executable(test_stack test_stack.c stack.c) -target_link_libraries(test_stack stack) \ No newline at end of file +add_executable(benchmark_stack benchmark_stack.c stack.c) \ No newline at end of file diff --git a/05_hw/benchmark_stack.c b/05_hw/benchmark_stack.c new file mode 100644 index 0000000..778626d --- /dev/null +++ b/05_hw/benchmark_stack.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include "stack.h" + +#define N 1000000 + +void benchmark_push(Stack* stack) { + clock_t start, end; + double cpu_time_used; + + printf("Running benchmark for push()...\n"); + start = clock(); + for (int i = 0; i < N; i++) { + push(stack, i); + } + end = clock(); + + cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; + printf("push(): Time taken for %d operations: %f seconds\n", N, cpu_time_used); +} + +void benchmark_pop(Stack* stack) { + clock_t start, end; + double cpu_time_used; + + printf("Running benchmark for pop()...\n"); + start = clock(); + for (int i = 0; i < N; i++) { + pop(stack); + } + end = clock(); + + cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; + printf("pop(): Time taken for %d operations: %f seconds\n", N, cpu_time_used); +} + +int main() { + Stack stack; + initStack(&stack); + + benchmark_push(&stack); + benchmark_pop(&stack); + destroyStack(&stack); + + return 0; +}