# 📚 Dynamic Array Library A simple, educational C implementation of a dynamic array (vector-like) data structure. > ⚠️ **Study Case Only** — This project is for **learning purposes** and should **NOT** be used in production environments. ## Overview This library provides a basic dynamic array implementation in C, similar to C++'s `std::vector` or Python's lists. It demonstrates fundamental concepts in systems programming: - **Memory management** — allocation, reallocation, deallocation - **Generic programming** — type-agnostic macros that work with any pointer type - **Unit testing** — with the Unity C testing framework ## ✨ Features - **Header-only** — just include `dynamic_array.h`, no compilation step needed - **Dynamic resizing** — automatically grows as elements are added - **Type-safe** — macros operate on typed pointers; direct indexing is fully typed - **Simple API** — a small set of macros for common operations ## 📁 Project Structure ``` dynamic_array/ ├── src/ │ ├── dynamic_array.h # Header-only implementation (public API) │ ├── test_dynamic_array.c # Unit tests │ └── CMakeLists.txt # Build configuration ├── submodules/ │ └── external/ │ └── unity/ # Unity test framework ├── CMakeLists.txt # Root CMake configuration ├── Makefile # Build automation └── README.md # This file ``` ## 🔧 Prerequisites **Linux-only project** - **CMake** ≥ 3.12 - **C compiler** (GCC recommended, Clang supported) - **Make** (optional, but recommended) - **build-essential** (on Ubuntu/Debian): `sudo apt-get install build-essential` ## 🔨 Building ### Using the Makefile (Recommended) ```bash make configure # Configure the project make build # Build the project make test # Run tests make install # Install the library make clean # Clean build artifacts ``` ### Using CMake Directly ```bash mkdir build && cd build cmake .. cmake --build . ctest --output-on-failure cmake --install . cd .. && rm -rf build ``` ## 💡 Usage ### Including the Library ```c #include "dynamic_array.h" // Create a typed array (works with any pointer type) int *arr = NULL; array_create(arr); // Add elements array_push_value(arr, 10); array_push_value(arr, 20); array_push_value(arr, 30); // Access elements directly via indexing int first = arr[0]; // 10 // Remove the last element array_pop(arr); // Inspect size and capacity via the header const ArrayHeader *header = array_get_header(arr); size_t size = header->size; // current number of elements size_t capacity = header->capacity; // allocated capacity // Cleanup array_destroy(arr); // frees memory and sets arr to NULL ``` ## 📖 API Reference ### Structures #### `ArrayHeader` Stored immediately before the array data in memory. Retrieve it with `array_get_header`. ```c typedef struct { size_t size; // Current number of elements size_t capacity; // Allocated capacity } ArrayHeader; ``` Memory layout: ``` [ ArrayHeader | elem 0 | elem 1 | ... ] ↑ pointer returned by array_create (and all macros) ``` ### Macros | Macro | Description | |-------|-------------| | `array_create(arr)` | Allocates a new array; sets `arr` to point to the first element | | `array_destroy(arr)` | Frees the array and sets `arr` to `NULL` | | `array_get_header(arr)` | Returns a pointer to the `ArrayHeader` for `arr` | | `array_push_value(arr, value)` | Appends `value`; grows the array automatically if needed | | `array_pop(arr)` | Removes the last element by decrementing `size` | ### Constants | Constant | Default | Description | |----------|---------|-------------| | `DYNAMIC_ARRAY_DEFAULT_ARRAY_SIZE` | `10` | Initial capacity allocated by `array_create` | | `DYNAMIC_ARRAY_CAPACITY_FACTOR` | `2` | Growth multiplier applied on resize | ## ✅ Testing Tests are written using the [Unity](http://www.throwtheswitch.org/unity) C testing framework. ```bash make test ``` Or directly with ctest: ```bash cd build && ctest --output-on-failure ``` ## 📦 Installation ### Default Installation ```bash make install ``` This installs to `~/.local/bin/dynamic_array/`: - **Header:** `include/dynamic_array.h` ### Custom Installation Directory ```bash make install INSTALL_PREFIX=/custom/path ``` Or set it as an environment variable: ```bash export INSTALL_PREFIX=$HOME/.local make install ``` ## ⚠️ Known Issues & Limitations - ⚠️ No bounds checking - ⚠️ `array_pop` does not return the removed element (use `arr[header->size - 1]` before popping) - ⚠️ Simple reallocation strategy (not optimized for performance) - ⚠️ Not thread-safe - ⚠️ `realloc` failure is not propagated to the caller - ⚠️ Educational purpose only — use established libraries for production ## 🚀 Future Improvements - [ ] Return value from `array_pop` - [ ] Propagate allocation failures - [ ] Add more comprehensive error handling - [ ] Implement shrinking / `array_reserve` - [ ] Add iterator support - [ ] Optimize memory allocation strategy - [ ] Add more test coverage ## 📄 License This project is for educational purposes. ## 📚 References - [CMake Documentation](https://cmake.org/documentation/) - [Unity Test Framework](http://www.throwtheswitch.org/unity) - [C Dynamic Memory Management](https://en.cppreference.com/w/c/memory) --- **Created for learning C programming concepts** 📚