From e48aecf36a0a68537d6c18f489b59feca54f639a Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Wed, 15 Apr 2026 20:16:32 -0300 Subject: [PATCH] chore: update README to enhance clarity and detail on dynamic array features --- README.md | 116 +++++++++++++++++++++++++++++------------------------- 1 file changed, 62 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index ed9fcd6..3885903 100644 --- a/README.md +++ b/README.md @@ -9,21 +9,22 @@ A simple, educational C implementation of a dynamic array (vector-like) data str 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** — using `void*` pointers -- **Type-safe macros** — for type casting and operations +- **Generic programming** — type-agnostic macros that work with any pointer type - **Unit testing** — with the Unity C testing framework + ## ✨ Features -- **Dynamic resizing** — Automatically grows as elements are added -- **Type-safe operations** — Macros for working with typed elements -- **Simple API** — Easy-to-use functions for common operations +- **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 ``` -test-meson/ +dynamic_array/ ├── src/ -│ ├── dynamic_array.c # Implementation -│ ├── dynamic_array.h # Public API header +│ ├── dynamic_array.h # Header-only implementation (public API) │ ├── test_dynamic_array.c # Unit tests │ └── CMakeLists.txt # Build configuration ├── submodules/ @@ -33,6 +34,7 @@ test-meson/ ├── Makefile # Build automation └── README.md # This file ``` + ## 🔧 Prerequisites **Linux-only project** @@ -41,6 +43,7 @@ test-meson/ - **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) @@ -63,6 +66,7 @@ ctest --output-on-failure cmake --install . cd .. && rm -rf build ``` + ## 💡 Usage ### Including the Library @@ -70,72 +74,70 @@ cd .. && rm -rf build ```c #include "dynamic_array.h" -// Create an array of integers -ArrayCreateOptions opts = { - .initial_size = 10, - .element_size = sizeof(int) -}; -Array *my_array = array_create(&opts); +// Create a typed array (works with any pointer type) +int *arr = NULL; +array_create(arr); // Add elements -int value = 42; -array_set_value(my_array, 0, &value); +array_push_value(arr, 10); +array_push_value(arr, 20); +array_push_value(arr, 30); -// Retrieve elements -int *retrieved = (int*)array_get_value(my_array, 0); +// Access elements directly via indexing +int first = arr[0]; // 10 -// Using type-safe macros -int result = array_set_value_as(int, my_array, 1, 100); +// Remove the last element +array_pop(arr); -// Get size and capacity -size_t size = array_get_size(my_array); -size_t capacity = array_get_capacity(my_array); +// 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_deconstructor(&my_array); +array_destroy(arr); // frees memory and sets arr to NULL ``` + ## 📖 API Reference ### Structures -#### `Array` +#### `ArrayHeader` + +Stored immediately before the array data in memory. Retrieve it with `array_get_header`. ```c typedef struct { - void *value; // Pointer to element data - size_t element_size; // Size of each element - size_t size; // Current number of elements - size_t capacity; // Allocated capacity -} Array; + size_t size; // Current number of elements + size_t capacity; // Allocated capacity +} ArrayHeader; ``` -#### `ArrayCreateOptions` +Memory layout: -```c -typedef struct { - int initial_size; // Initial capacity - size_t element_size; // Size of each element type -} ArrayCreateOptions; ``` - -### Functions - -| Function | Description | -|----------|-------------| -| `Array *array_create(const ArrayCreateOptions *options)` | Creates a new dynamic array | -| `void array_deconstructor(Array **pp_array)` | Frees allocated memory and sets pointer to NULL | -| `void array_resize(Array *p_array, size_t new_size)` | Resizes the array's capacity | -| `void *array_get_value(const Array *p_array, size_t index)` | Retrieves a pointer to the element at index | -| `void array_set_value(Array *p_array, size_t index, const void *value)` | Sets the element at index | -| `size_t array_get_size(const Array *p_array)` | Returns the current number of elements | -| `size_t array_get_capacity(const Array *p_array)` | Returns the allocated capacity | +[ ArrayHeader | elem 0 | elem 1 | ... ] + ↑ + pointer returned by array_create (and all macros) +``` ### Macros | Macro | Description | |-------|-------------| -| `array_get_value_as(type, arr, idx)` | Type-safe retrieval of elements | -| `array_set_value_as(type, arr, idx, value)` | Type-safe setting of elements (with type checking) | +| `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. @@ -149,6 +151,7 @@ Or directly with ctest: ```bash cd build && ctest --output-on-failure ``` + ## 📦 Installation ### Default Installation @@ -158,7 +161,6 @@ make install ``` This installs to `~/.local/bin/dynamic_array/`: -- **Library:** `lib/libdynamic_array.a` - **Header:** `include/dynamic_array.h` ### Custom Installation Directory @@ -173,20 +175,26 @@ Or set it as an environment variable: export INSTALL_PREFIX=$HOME/.local make install ``` + ## ⚠️ Known Issues & Limitations -- ⚠️ No bounds checking in release builds +- ⚠️ 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 -- ⚠️ Limited error handling +- ⚠️ `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 functionality +- [ ] Implement shrinking / `array_reserve` - [ ] Add iterator support - [ ] Optimize memory allocation strategy - [ ] Add more test coverage + ## 📄 License This project is for educational purposes. -- 2.49.1