From 8d9f0c100234fda085f98d86f687136ac43a236a Mon Sep 17 00:00:00 2001 From: s2pid0 Date: Tue, 7 Jan 2025 23:05:38 +0300 Subject: [PATCH 1/4] fix: pop and isEmpty bugs in stack.c --- .gitignore | 3 +++ 05_hw/CMakeLists.txt | 1 + 05_hw/main.c | 1 - 05_hw/stack.c | 6 ++++-- 4 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca5637a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vscode +05_hw/.idea +05_hw/cmake-build-debug \ No newline at end of file diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 6f5e398..995049d 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -4,4 +4,5 @@ project(stack) add_library(stack stack.c) add_executable(main main.c) + target_link_libraries(main stack) diff --git a/05_hw/main.c b/05_hw/main.c index fded814..ff39bce 100644 --- a/05_hw/main.c +++ b/05_hw/main.c @@ -8,7 +8,6 @@ int main() { push(&stack, 10); push(&stack, 20); - push(&stack, 30); printf("After pushing elements:\n"); traverseStack(&stack); diff --git a/05_hw/stack.c b/05_hw/stack.c index 0964440..635cdcc 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.c @@ -31,7 +31,10 @@ void push(Stack* stack, int data) { void pop(Stack* stack) { Node* temp = stack->top; - stack->top = stack->top->next; + if (temp!=NULL) { + stack->top = stack->top->next; + free(temp); + } } Node* searchByValue(Stack* stack, int value) { @@ -72,7 +75,6 @@ void traverseStack(Stack* stack) { } bool isEmpty(Stack* stack) { - free(stack->top); return stack->top == NULL; } From fcb66e76160dd8de67a4388d4b13cbf1c9cd910c Mon Sep 17 00:00:00 2001 From: s2pid0 Date: Wed, 8 Jan 2025 16:34:06 +0300 Subject: [PATCH 2/4] fix: bugs in destroyStack. add gtests to project --- .gitignore | 6 ++++-- 05_hw/CMakeLists.txt | 14 +++++++++++--- 05_hw/{main.c => main.cpp} | 3 +++ 05_hw/{stack.c => stack.cpp} | 11 +++++------ 4 files changed, 23 insertions(+), 11 deletions(-) rename 05_hw/{main.c => main.cpp} (92%) rename 05_hw/{stack.c => stack.cpp} (92%) diff --git a/.gitignore b/.gitignore index ca5637a..c94f4b9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ -.vscode +.vs 05_hw/.idea -05_hw/cmake-build-debug \ No newline at end of file +05_hw/cmake-build-debug +05_hw/googletest +05_hw/out \ No newline at end of file diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 995049d..3ee2d94 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -1,8 +1,16 @@ cmake_minimum_required(VERSION 3.10) project(stack) -add_library(stack stack.c) +set(GOOGLETEST_VERSION 1.15.2) -add_executable(main main.c) +enable_testing() +add_subdirectory(googletest) +include_directories(googletest/include) -target_link_libraries(main stack) +add_library(stack stack.cpp) + +add_executable(tests tests.cpp) +target_link_libraries(tests PRIVATE gtest stack) + +add_executable(main main.cpp) +target_link_libraries(main stack) \ No newline at end of file diff --git a/05_hw/main.c b/05_hw/main.cpp similarity index 92% rename from 05_hw/main.c rename to 05_hw/main.cpp index ff39bce..a162bce 100644 --- a/05_hw/main.c +++ b/05_hw/main.cpp @@ -29,6 +29,9 @@ int main() { printf("Top element: %d\n", topElement->data); } + destroyStack(&stack); + traverseStack(&stack); + return 0; } diff --git a/05_hw/stack.c b/05_hw/stack.cpp similarity index 92% rename from 05_hw/stack.c rename to 05_hw/stack.cpp index 635cdcc..d8efb2f 100644 --- a/05_hw/stack.c +++ b/05_hw/stack.cpp @@ -15,12 +15,8 @@ void initStack(Stack* stack) { } void destroyStack(Stack* stack) { - Node* current = stack->top; - while (current != NULL) { - Node *tmp = current; - current = current->next; - free(tmp); - } + while (stack->top != NULL) + pop(stack); } void push(Stack* stack, int data) { @@ -34,6 +30,8 @@ void pop(Stack* stack) { if (temp!=NULL) { stack->top = stack->top->next; free(temp); + } else { + return; } } @@ -43,6 +41,7 @@ Node* searchByValue(Stack* stack, int value) { if (current->data == value) { return current; } + current = current->next; } return NULL; } From 09186d4c38fc91119cc33c6e94d9b331c0d1ec1a Mon Sep 17 00:00:00 2001 From: s2pid0 Date: Thu, 9 Jan 2025 03:47:41 +0300 Subject: [PATCH 3/4] test: add tests for all stack.cpp methods build: changed CMake file, add gcov feat: add benchmark --- .gitignore | 7 ++- 05_hw/CMakeLists.txt | 51 +++++++++++++++++++--- 05_hw/bm.cpp | 55 +++++++++++++++++++++++ 05_hw/tests.cpp | 101 +++++++++++++++++++++++++++++++++++++++++++ README.md | 1 - 5 files changed, 204 insertions(+), 11 deletions(-) create mode 100644 05_hw/bm.cpp create mode 100644 05_hw/tests.cpp delete mode 100644 README.md diff --git a/.gitignore b/.gitignore index c94f4b9..af67b40 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .vs -05_hw/.idea -05_hw/cmake-build-debug -05_hw/googletest -05_hw/out \ No newline at end of file +05_hw/.vscode +05_hw/benchmark +05_hw/build \ No newline at end of file diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 3ee2d94..7e9c5f2 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -1,16 +1,55 @@ +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +add_compile_options(-std=c++17 -D_GLIBCXX_USE_C99) + cmake_minimum_required(VERSION 3.10) project(stack) -set(GOOGLETEST_VERSION 1.15.2) +# Указываем путь к заголовкам GTest +# include_directories("C:/msys64/mingw64/include") -enable_testing() -add_subdirectory(googletest) -include_directories(googletest/include) +# # Указываем путь к библиотекам GTest +# link_directories("C:/msys64/mingw64/lib") + +# Линкуем GTest +# target_link_libraries(tests PRIVATE gtest gtest_main) + + + +find_package(GTest REQUIRED) + + +if(WIN32) + set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +endif() add_library(stack stack.cpp) +add_executable(main main.cpp) +target_link_libraries(main stack) + + add_executable(tests tests.cpp) target_link_libraries(tests PRIVATE gtest stack) +target_link_libraries(stack PRIVATE gcov) -add_executable(main main.cpp) -target_link_libraries(main stack) \ No newline at end of file +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + target_compile_options(tests PRIVATE --coverage) + target_link_options(tests PRIVATE --coverage) + target_compile_options(stack PRIVATE --coverage) + target_link_options(stack PRIVATE --coverage) +endif() + +enable_testing() +# add_test(NAME tests COMMAND tests) +add_test(NAME stack_tests COMMAND tests) + + +set(BENCHMARK_ENABLE_TESTING OFF) +add_subdirectory(benchmark) +include_directories(benchmark/include) + +add_executable(bm bm.cpp) +target_link_libraries(bm PRIVATE benchmark::benchmark stack) diff --git a/05_hw/bm.cpp b/05_hw/bm.cpp new file mode 100644 index 0000000..c711a4d --- /dev/null +++ b/05_hw/bm.cpp @@ -0,0 +1,55 @@ +#include +#include "stack.h" + +class StackBench : public benchmark::Fixture +{ + void SetUp(::benchmark::State& state) + { + stack = new Stack(); + } + + void TearDown(::benchmark::State& state) + { + delete stack; + } + +public: + Stack* stack; +}; + +BENCHMARK_DEFINE_F(StackBench, PushBench)(benchmark::State& st) +{ + for (auto _ : st) + { + for (int i = 0; i < st.range(0); i++) + push(stack, i); + } +} + +BENCHMARK_DEFINE_F(StackBench, PopBench)(benchmark::State& st) +{ + for (int i = 0; i < st.range(0); i++) + push(stack, i); + + for (auto _ : st) + { + for (int i = 0; i < st.range(0); i++) + pop(stack); + } +} + +BENCHMARK_REGISTER_F(StackBench, PushBench) +->Arg(100) +->Arg(1000) +->Arg(10000) +->Arg(100000) +->Arg(1000000); + +BENCHMARK_REGISTER_F(StackBench, PopBench) +->Arg(100) +->Arg(1000) +->Arg(10000) +->Arg(100000) +->Arg(1000000); + +BENCHMARK_MAIN(); diff --git a/05_hw/tests.cpp b/05_hw/tests.cpp new file mode 100644 index 0000000..ff9a295 --- /dev/null +++ b/05_hw/tests.cpp @@ -0,0 +1,101 @@ +#include +#include "stack.h" + +using namespace std; + +class StackTest : public testing::Test +{ + void SetUp() override + { + stack = new Stack(); + } + + void TearDown() override { + delete stack; + } + +public: + Stack* stack; +}; + +TEST_F(StackTest, initStackTest) { + Stack f; + initStack(&f); + EXPECT_EQ(isEmpty(&f), true); + delete &f; +} + +TEST_F(StackTest, isEmptyTest) { + EXPECT_EQ(isEmpty(stack), true); +} + +TEST_F(StackTest, pushTest) { + push(stack, 44); + EXPECT_EQ(getTop(stack)->data, 44); +} + +TEST_F(StackTest, popTest) { + push(stack, 0); + push(stack, 3); + push(stack, 11); + pop(stack); + EXPECT_EQ(getTop(stack)->data, 3); +} + +TEST_F(StackTest, EmptyPopTest) { + pop(stack); + EXPECT_EQ(getTop(stack), nullptr); +} + + +TEST_F(StackTest, destroyStackTests) { + push(stack, -12); + push(stack, -31); + push(stack, 2); + push(stack, 832); + + destroyStack(stack); + + EXPECT_EQ(getTop(stack), nullptr); +} + +TEST_F(StackTest, searchByValueTest) { + push(stack, 12); + push(stack, -2); + push(stack, 72); + + EXPECT_EQ(searchByValue(stack, -2)->data, -2); +} + +TEST_F(StackTest, searchByIndexTest) { + push(stack, 12); + push(stack, 2); + push(stack, 72); + + EXPECT_EQ(searchByIndex(stack, 2)->data, 12); +} + +TEST_F(StackTest, traverseStackTest) { + testing::internal::CaptureStdout(); + + push(stack, 22129); + push(stack, -12); + push(stack, 0); + push(stack, 51242); + push(stack, -33); + + traverseStack(stack); + + std::string expected = "Stack elements: -33 51242 0 -12 22129 \n"; + std::string output = testing::internal::GetCapturedStdout(); + + EXPECT_EQ(expected, output); +} + + +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 610bb77..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# Читать README в 05_hw From bbbd0f55d7f55abd65761d9b7de211ba14725217 Mon Sep 17 00:00:00 2001 From: s2pid0 Date: Thu, 9 Jan 2025 21:00:42 +0300 Subject: [PATCH 4/4] add sanitazers for tests. fix initStackTest --- 05_hw/CMakeLists.txt | 37 ++++++++++++++++++++----------------- 05_hw/main.cpp | 3 +-- 05_hw/tests.cpp | 1 - 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/05_hw/CMakeLists.txt b/05_hw/CMakeLists.txt index 7e9c5f2..5416071 100644 --- a/05_hw/CMakeLists.txt +++ b/05_hw/CMakeLists.txt @@ -2,21 +2,11 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -add_compile_options(-std=c++17 -D_GLIBCXX_USE_C99) +add_compile_options(-std=c++17 -D_GLIBCXX_USE_C99 -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++) cmake_minimum_required(VERSION 3.10) project(stack) -# Указываем путь к заголовкам GTest -# include_directories("C:/msys64/mingw64/include") - -# # Указываем путь к библиотекам GTest -# link_directories("C:/msys64/mingw64/lib") - -# Линкуем GTest -# target_link_libraries(tests PRIVATE gtest gtest_main) - - find_package(GTest REQUIRED) @@ -30,16 +20,29 @@ add_library(stack stack.cpp) add_executable(main main.cpp) target_link_libraries(main stack) - add_executable(tests tests.cpp) target_link_libraries(tests PRIVATE gtest stack) target_link_libraries(stack PRIVATE gcov) -if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_options(tests PRIVATE --coverage) - target_link_options(tests PRIVATE --coverage) - target_compile_options(stack PRIVATE --coverage) - target_link_options(stack PRIVATE --coverage) +if(CMAKE_EXPORT_COMPILE_COMMANDS) + find_program(CLANG_EXECUTABLE "C:/msys64/mingw64/bin/clang.exe") + add_custom_target(analyze + COMMAND + analyze-build --cdb ${PROJECT_BINARY_DIR}/compile_commands.json + --use-analyzer ${CLANG_EXECUTABLE} + --output ${PROJECT_BINARY_DIR}/analyzer + ) +endif() + +target_compile_options(tests PRIVATE --coverage) +target_link_options(tests PRIVATE --coverage) +target_compile_options(stack PRIVATE --coverage) +target_link_options(stack PRIVATE --coverage) + + +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_compile_options(tests PRIVATE -fsanitize=address -fno-omit-frame-pointer) + target_link_options(tests PRIVATE -fsanitize=address) endif() enable_testing() diff --git a/05_hw/main.cpp b/05_hw/main.cpp index a162bce..b1c285c 100644 --- a/05_hw/main.cpp +++ b/05_hw/main.cpp @@ -8,6 +8,7 @@ int main() { push(&stack, 10); push(&stack, 20); + push(&stack, 30); printf("After pushing elements:\n"); traverseStack(&stack); @@ -29,8 +30,6 @@ int main() { printf("Top element: %d\n", topElement->data); } - destroyStack(&stack); - traverseStack(&stack); return 0; } diff --git a/05_hw/tests.cpp b/05_hw/tests.cpp index ff9a295..14ad63e 100644 --- a/05_hw/tests.cpp +++ b/05_hw/tests.cpp @@ -22,7 +22,6 @@ TEST_F(StackTest, initStackTest) { Stack f; initStack(&f); EXPECT_EQ(isEmpty(&f), true); - delete &f; } TEST_F(StackTest, isEmptyTest) {