From f63d3eb6d97e18a7d1c5bd5fef502536f795fd10 Mon Sep 17 00:00:00 2001 From: Gleb Date: Tue, 25 Nov 2025 23:53:51 +0300 Subject: [PATCH 1/9] Fix stack.c and stack.h --- 05_hw/stack.c | 31 ++++++++++++++----- 05_hw/stack.c.bak | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 05_hw/stack.h | 4 +-- 05_hw/stack.h.bak | 40 ++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 10 deletions(-) create mode 100644 05_hw/stack.c.bak create mode 100644 05_hw/stack.h.bak diff --git a/05_hw/stack.c b/05_hw/stack.c index 0964440..bea5d4e 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -1,10 +1,11 @@ #include #include - #include "stack.h" Node* createNode(int data) { Node* newNode = (Node*)malloc(sizeof(Node)); + if (!newNode) return NULL; + newNode->data = data; newNode->next = NULL; return newNode; @@ -17,21 +18,33 @@ 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) { Node* newNode = createNode(data); + if (!newNode) return; + newNode->next = stack->top; stack->top = newNode; } -void pop(Stack* stack) { +int pop(Stack* stack) { + if (stack->top == NULL) { + return 0; + } + Node* temp = stack->top; - stack->top = stack->top->next; + int value = temp->data; + + stack->top = temp->next; + free(temp); + + return value; } Node* searchByValue(Stack* stack, int value) { @@ -40,6 +53,7 @@ Node* searchByValue(Stack* stack, int value) { if (current->data == value) { return current; } + current = current->next; } return NULL; } @@ -47,6 +61,7 @@ Node* searchByValue(Stack* stack, int value) { Node* searchByIndex(Stack* stack, int index) { Node* current = stack->top; int count = 0; + while (current != NULL) { if (count == index) { return current; @@ -64,15 +79,15 @@ Node* getTop(Stack* stack) { void traverseStack(Stack* stack) { Node* current = stack->top; printf("Stack elements: "); + while (current != NULL) { printf("%d ", current->data); current = current->next; } + printf("\n"); } bool isEmpty(Stack* stack) { - free(stack->top); return stack->top == NULL; -} - +} \ No newline at end of file diff --git a/05_hw/stack.c.bak b/05_hw/stack.c.bak new file mode 100644 index 0000000..0964440 --- /dev/null +++ b/05_hw/stack.c.bak @@ -0,0 +1,78 @@ +#include +#include + +#include "stack.h" + +Node* createNode(int data) { + Node* newNode = (Node*)malloc(sizeof(Node)); + newNode->data = data; + newNode->next = NULL; + return newNode; +} + +void initStack(Stack* stack) { + stack->top = NULL; +} + +void destroyStack(Stack* stack) { + Node* current = stack->top; + while (current != NULL) { + Node *tmp = current; + current = current->next; + free(tmp); + } +} + +void push(Stack* stack, int data) { + Node* newNode = createNode(data); + newNode->next = stack->top; + stack->top = newNode; +} + +void pop(Stack* stack) { + Node* temp = stack->top; + stack->top = stack->top->next; +} + +Node* searchByValue(Stack* stack, int value) { + Node* current = stack->top; + while (current != NULL) { + if (current->data == value) { + return current; + } + } + return NULL; +} + +Node* searchByIndex(Stack* stack, int index) { + Node* current = stack->top; + int count = 0; + while (current != NULL) { + if (count == index) { + return current; + } + count++; + current = current->next; + } + return NULL; +} + +Node* getTop(Stack* stack) { + return stack->top; +} + +void traverseStack(Stack* stack) { + Node* current = stack->top; + printf("Stack elements: "); + while (current != NULL) { + printf("%d ", current->data); + current = current->next; + } + printf("\n"); +} + +bool isEmpty(Stack* stack) { + free(stack->top); + return stack->top == NULL; +} + diff --git a/05_hw/stack.h b/05_hw/stack.h index ef0734e..86f3efa 100644 --- a/05_hw/stack.h +++ b/05_hw/stack.h @@ -23,7 +23,7 @@ void destroyStack(Stack *stack); void push(Stack* stack, int data); -void pop(Stack* stack); +int pop(Stack* stack); Node* searchByValue(Stack* stack, int value); @@ -37,4 +37,4 @@ bool isEmpty(Stack* stack); #ifdef __cplusplus } -#endif +#endif \ No newline at end of file diff --git a/05_hw/stack.h.bak b/05_hw/stack.h.bak new file mode 100644 index 0000000..ef0734e --- /dev/null +++ b/05_hw/stack.h.bak @@ -0,0 +1,40 @@ +#pragma once + +#include + +typedef struct Node { + int data; + struct Node* next; +} Node; + +typedef struct Stack { + Node* top; +} Stack; + +#ifdef __cplusplus +extern "C" { +#endif + +Node* createNode(int data); + +void initStack(Stack* stack); + +void destroyStack(Stack *stack); + +void push(Stack* stack, int data); + +void pop(Stack* stack); + +Node* searchByValue(Stack* stack, int value); + +Node* searchByIndex(Stack* stack, int index); + +Node* getTop(Stack* stack); + +void traverseStack(Stack* stack); + +bool isEmpty(Stack* stack); + +#ifdef __cplusplus +} +#endif From 01be2410c9439f80d7edcb0663d617540b3e2922 Mon Sep 17 00:00:00 2001 From: Gleb Date: Tue, 25 Nov 2025 23:55:05 +0300 Subject: [PATCH 2/9] Fix stack.c and stack.h --- 05_hw/stack.c.bak | 78 ----------------------------------------------- 05_hw/stack.h.bak | 40 ------------------------ 2 files changed, 118 deletions(-) delete mode 100644 05_hw/stack.c.bak delete mode 100644 05_hw/stack.h.bak diff --git a/05_hw/stack.c.bak b/05_hw/stack.c.bak deleted file mode 100644 index 0964440..0000000 --- a/05_hw/stack.c.bak +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include - -#include "stack.h" - -Node* createNode(int data) { - Node* newNode = (Node*)malloc(sizeof(Node)); - newNode->data = data; - newNode->next = NULL; - return newNode; -} - -void initStack(Stack* stack) { - stack->top = NULL; -} - -void destroyStack(Stack* stack) { - Node* current = stack->top; - while (current != NULL) { - Node *tmp = current; - current = current->next; - free(tmp); - } -} - -void push(Stack* stack, int data) { - Node* newNode = createNode(data); - newNode->next = stack->top; - stack->top = newNode; -} - -void pop(Stack* stack) { - Node* temp = stack->top; - stack->top = stack->top->next; -} - -Node* searchByValue(Stack* stack, int value) { - Node* current = stack->top; - while (current != NULL) { - if (current->data == value) { - return current; - } - } - return NULL; -} - -Node* searchByIndex(Stack* stack, int index) { - Node* current = stack->top; - int count = 0; - while (current != NULL) { - if (count == index) { - return current; - } - count++; - current = current->next; - } - return NULL; -} - -Node* getTop(Stack* stack) { - return stack->top; -} - -void traverseStack(Stack* stack) { - Node* current = stack->top; - printf("Stack elements: "); - while (current != NULL) { - printf("%d ", current->data); - current = current->next; - } - printf("\n"); -} - -bool isEmpty(Stack* stack) { - free(stack->top); - return stack->top == NULL; -} - diff --git a/05_hw/stack.h.bak b/05_hw/stack.h.bak deleted file mode 100644 index ef0734e..0000000 --- a/05_hw/stack.h.bak +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include - -typedef struct Node { - int data; - struct Node* next; -} Node; - -typedef struct Stack { - Node* top; -} Stack; - -#ifdef __cplusplus -extern "C" { -#endif - -Node* createNode(int data); - -void initStack(Stack* stack); - -void destroyStack(Stack *stack); - -void push(Stack* stack, int data); - -void pop(Stack* stack); - -Node* searchByValue(Stack* stack, int value); - -Node* searchByIndex(Stack* stack, int index); - -Node* getTop(Stack* stack); - -void traverseStack(Stack* stack); - -bool isEmpty(Stack* stack); - -#ifdef __cplusplus -} -#endif From bd3419ee07b8047cc41102d54a22bdf243ea1d49 Mon Sep 17 00:00:00 2001 From: Gleb Date: Wed, 26 Nov 2025 00:02:37 +0300 Subject: [PATCH 3/9] Add test.c --- 05_hw/test.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++ 05_hw/test.c.bak | 0 2 files changed, 105 insertions(+) create mode 100644 05_hw/test.c create mode 100644 05_hw/test.c.bak diff --git a/05_hw/test.c b/05_hw/test.c new file mode 100644 index 0000000..02def1a --- /dev/null +++ b/05_hw/test.c @@ -0,0 +1,105 @@ +#include +#include + +#include "stack.h" + +void test_initStack(void) { + Stack s; + initStack(&s); + CU_ASSERT_PTR_NULL(s.top); +} + +void test_push_and_getTop(void) { + Stack s; + initStack(&s); + + push(&s, 10); + CU_ASSERT_PTR_NOT_NULL(s.top); + CU_ASSERT_EQUAL(getTop(&s)->data, 10); + + push(&s, 20); + CU_ASSERT_EQUAL(getTop(&s)->data, 20); +} + +void test_pop(void) { + Stack s; + initStack(&s); + + push(&s, 10); + push(&s, 20); + + pop(&s); + CU_ASSERT_EQUAL(getTop(&s)->data, 10); + + pop(&s); + CU_ASSERT_PTR_NULL(getTop(&s)); +} + +void test_searchByValue(void) { + Stack s; + initStack(&s); + + push(&s, 5); + push(&s, 10); + push(&s, 15); + + CU_ASSERT_PTR_NOT_NULL(searchByValue(&s, 10)); + CU_ASSERT_PTR_NULL(searchByValue(&s, 999)); +} + +void test_searchByIndex(void) { + Stack s; + initStack(&s); + + push(&s, 1); // index 0 + push(&s, 2); // index 1 + push(&s, 3); // index 2 + + CU_ASSERT_EQUAL(searchByIndex(&s, 0)->data, 3); + CU_ASSERT_EQUAL(searchByIndex(&s, 1)->data, 2); + CU_ASSERT_EQUAL(searchByIndex(&s, 2)->data, 1); + CU_ASSERT_PTR_NULL(searchByIndex(&s, 10)); +} + +void test_isEmpty(void) { + Stack s; + initStack(&s); + CU_ASSERT_TRUE(isEmpty(&s)); + + push(&s, 123); + CU_ASSERT_FALSE(isEmpty(&s)); +} + +void test_destroyStack(void) { + Stack s; + initStack(&s); + + push(&s, 1); + push(&s, 2); + push(&s, 3); + + destroyStack(&s); + + CU_ASSERT_PTR_NULL(s.top); +} + + +int main() { + CU_initialize_registry(); + + CU_pSuite suite = CU_add_suite("Stack tests", 0, 0); + + CU_add_test(suite, "initStack", test_initStack); + CU_add_test(suite, "push & getTop", test_push_and_getTop); + CU_add_test(suite, "pop", test_pop); + CU_add_test(suite, "searchByValue", test_searchByValue); + CU_add_test(suite, "searchByIndex", test_searchByIndex); + CU_add_test(suite, "isEmpty", test_isEmpty); + CU_add_test(suite, "destroyStack", test_destroyStack); + + CU_basic_set_mode(CU_BRM_VERBOSE); + CU_basic_run_tests(); + CU_cleanup_registry(); + + return 0; +} \ No newline at end of file diff --git a/05_hw/test.c.bak b/05_hw/test.c.bak new file mode 100644 index 0000000..e69de29 From 6c56beae3786ec4feb1f58f2be615dab190a2e4b Mon Sep 17 00:00:00 2001 From: Gleb Date: Wed, 26 Nov 2025 00:02:48 +0300 Subject: [PATCH 4/9] Add test.c --- 05_hw/test.c.bak | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 05_hw/test.c.bak diff --git a/05_hw/test.c.bak b/05_hw/test.c.bak deleted file mode 100644 index e69de29..0000000 From e5e1e6524d42f200782b1031bd57b73b61265ef5 Mon Sep 17 00:00:00 2001 From: Gleb Date: Wed, 26 Nov 2025 15:07:34 +0300 Subject: [PATCH 5/9] Add analyzer, report.txt --- 05_hw/report.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 05_hw/report.txt diff --git a/05_hw/report.txt b/05_hw/report.txt new file mode 100644 index 0000000..b0bc597 --- /dev/null +++ b/05_hw/report.txt @@ -0,0 +1,17 @@ +Running: cppcheck --enable=all --template={"file":"{file}","line":{line},"column":{column},"severity":"{severity}","message":"{message}","id":"{id}"} c:\Users\User\Desktop\works\lecture-testing-task-main\05_hw\ + +Checking c:\Users\User\Desktop\works\lecture-testing-task-main\05_hw\stack.h ... +{"file":"c:\\Users\\User\\Desktop\\works\\lecture-testing-task-main\\05_hw\\stack.h","line":1,"column":0,"severity":"information","message":"Include file: not found. Please note: Cppcheck does not need standard library headers to get proper results.","id":"missingIncludeSystem"}, + +Checking c:\Users\User\Desktop\works\lecture-testing-task-main\05_hw\stack.c ... +{"file":"c:\\Users\\User\\Desktop\\works\\lecture-testing-task-main\\05_hw\\stack.c","line":1,"column":0,"severity":"information","message":"Include file: not found. Please note: Cppcheck does not need standard library headers to get proper results.","id":"missingIncludeSystem"}, +{"file":"c:\\Users\\User\\Desktop\\works\\lecture-testing-task-main\\05_hw\\stack.c","line":2,"column":0,"severity":"information","message":"Include file: not found. Please note: Cppcheck does not need standard library headers to get proper results.","id":"missingIncludeSystem"}, + +{"file":"c:\\Users\\User\\Desktop\\works\\lecture-testing-task-main\\05_hw\\stack.c","line":31,"column":5,"severity":"warning","message":"Returning 0 from pop() may be misleading: 0 is also valid data value.","id":"inconclusiveReturnValue"}, + +{"file":"c:\\Users\\User\\Desktop\\works\\lecture-testing-task-main\\05_hw\\stack.c","line":16,"column":5,"severity":"style","message":"Parameter stack can be null pointer.","id":"nullPointerRedundantCheck"}, + +{"file":"c:\\Users\\User\\Desktop\\works\\lecture-testing-task-main\\05_hw\\stack.c","line":67,"column":5,"severity":"style","message":"Found printf without newline. This may cause performance issues.","id":"performancePrintfWithoutNewline"}, + +Checking c:\Users\User\Desktop\works\lecture-testing-task-main\05_hw\main.c ... +{"file":"c:\\Users\\User\\Desktop\\works\\lecture-testing-task-main\\05_hw\\main.c","line":3,"column":0,"severity":"information","message":"Include file: not found. Please note: Cppcheck does not need standard library headers to get proper results.","id":"missingIncludeSystem"}, \ No newline at end of file From dc6bea27683f6cf6b7d639f88d29310c21c34841 Mon Sep 17 00:00:00 2001 From: Gleb Date: Wed, 26 Nov 2025 20:45:55 +0300 Subject: [PATCH 6/9] use sanitizer, update test.c --- 05_hw/test.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/05_hw/test.c b/05_hw/test.c index 02def1a..2c5686e 100644 --- a/05_hw/test.c +++ b/05_hw/test.c @@ -7,6 +7,7 @@ void test_initStack(void) { Stack s; initStack(&s); CU_ASSERT_PTR_NULL(s.top); + destroyStack(&s); } void test_push_and_getTop(void) { @@ -19,6 +20,8 @@ void test_push_and_getTop(void) { push(&s, 20); CU_ASSERT_EQUAL(getTop(&s)->data, 20); + + destroyStack(&s); } void test_pop(void) { @@ -33,6 +36,8 @@ void test_pop(void) { pop(&s); CU_ASSERT_PTR_NULL(getTop(&s)); + + destroyStack(&s); } void test_searchByValue(void) { @@ -45,20 +50,24 @@ void test_searchByValue(void) { CU_ASSERT_PTR_NOT_NULL(searchByValue(&s, 10)); CU_ASSERT_PTR_NULL(searchByValue(&s, 999)); + + destroyStack(&s); } void test_searchByIndex(void) { Stack s; initStack(&s); - push(&s, 1); // index 0 - push(&s, 2); // index 1 - push(&s, 3); // index 2 + push(&s, 1); + push(&s, 2); + push(&s, 3); CU_ASSERT_EQUAL(searchByIndex(&s, 0)->data, 3); CU_ASSERT_EQUAL(searchByIndex(&s, 1)->data, 2); CU_ASSERT_EQUAL(searchByIndex(&s, 2)->data, 1); CU_ASSERT_PTR_NULL(searchByIndex(&s, 10)); + + destroyStack(&s); } void test_isEmpty(void) { @@ -68,6 +77,8 @@ void test_isEmpty(void) { push(&s, 123); CU_ASSERT_FALSE(isEmpty(&s)); + + destroyStack(&s); } void test_destroyStack(void) { @@ -81,8 +92,9 @@ void test_destroyStack(void) { destroyStack(&s); CU_ASSERT_PTR_NULL(s.top); -} + destroyStack(&s); +} int main() { CU_initialize_registry(); From 105e714a953d6215cf368cfb265fd862ea72aa8d Mon Sep 17 00:00:00 2001 From: Gleb Date: Wed, 26 Nov 2025 20:56:15 +0300 Subject: [PATCH 7/9] add benchmark.c --- 05_hw/benchmark.c | 62 +++++++++++++++++++++++++++++++++++++++++++ 05_hw/benchmark.c.bak | 0 2 files changed, 62 insertions(+) create mode 100644 05_hw/benchmark.c create mode 100644 05_hw/benchmark.c.bak diff --git a/05_hw/benchmark.c b/05_hw/benchmark.c new file mode 100644 index 0000000..4ef62c8 --- /dev/null +++ b/05_hw/benchmark.c @@ -0,0 +1,62 @@ +#include +#include +#include "stack.h" + +#define N 1000000 + +void benchmark_push() { + Stack s; + initStack(&s); + + clock_t start = clock(); + + for (int i = 0; i < N; i++) { + push(&s, i); + } + + clock_t end = clock(); + + double elapsed_ms = ((double)(end - start) / CLOCKS_PER_SEC) * 1000.0; + + printf("Push benchmark:\n"); + printf(" Total pushes: %d\n", N); + printf(" Total time: %.3f ms\n", elapsed_ms); + printf(" Avg per push: %.6f microseconds\n\n", (elapsed_ms * 1000.0) / N); + + destroyStack(&s); +} + +// Функция для измерения pop() +void benchmark_pop() { + Stack s; + initStack(&s); + + // Заполняем стек заранее + for (int i = 0; i < N; i++) { + push(&s, i); + } + + clock_t start = clock(); + + for (int i = 0; i < N; i++) { + pop(&s); + } + + clock_t end = clock(); + + double elapsed_ms = ((double)(end - start) / CLOCKS_PER_SEC) * 1000.0; + + printf("Pop benchmark:\n"); + printf(" Total pops: %d\n", N); + printf(" Total time: %.3f ms\n", elapsed_ms); + printf(" Avg per pop: %.6f microseconds\n\n", (elapsed_ms * 1000.0) / N); +} + +int main() { + printf("=== Stack benchmark ===\n\n"); + + benchmark_push(); + benchmark_pop(); + + return 0; +} \ No newline at end of file diff --git a/05_hw/benchmark.c.bak b/05_hw/benchmark.c.bak new file mode 100644 index 0000000..e69de29 From a3f8b7614b6d41d81314a2116d04ec594bedecb6 Mon Sep 17 00:00:00 2001 From: Gleb Date: Wed, 26 Nov 2025 20:56:27 +0300 Subject: [PATCH 8/9] add benchmark.c --- 05_hw/benchmark.c.bak | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 05_hw/benchmark.c.bak diff --git a/05_hw/benchmark.c.bak b/05_hw/benchmark.c.bak deleted file mode 100644 index e69de29..0000000 From 76224f4d73bae28fb75aafb1132f5755793d1698 Mon Sep 17 00:00:00 2001 From: Gleb Date: Wed, 26 Nov 2025 21:26:35 +0300 Subject: [PATCH 9/9] add c-ci.yml --- .github/workflows/c-ci.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 .github/workflows/c-ci.yml diff --git a/.github/workflows/c-ci.yml b/.github/workflows/c-ci.yml new file mode 100644 index 0000000..2ff9066 --- /dev/null +++ b/.github/workflows/c-ci.yml @@ -0,0 +1,28 @@ +name: C/C++ CI + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install GCC and tooling + run: | + sudo apt-get update + sudo apt-get install -y gcc build-essential + + - name: Build tests with address sanitizer + run: | + gcc -fsanitize=address -g 05_hw/stack.c 05_hw/tests.c -o tests.exe + + - name: Run tests + run: | + ./tests.exe \ No newline at end of file