chore: update README to enhance clarity and detail on dynamic array features #2

Merged
HideyoshiNakazone merged 1 commits from chore/better-readme into main 2026-04-15 23:22:01 +00:00
Showing only changes of commit e48aecf36a - Show all commits

112
README.md
View File

@@ -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: 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 - **Memory management** — allocation, reallocation, deallocation
- **Generic programming** — using `void*` pointers - **Generic programming** — type-agnostic macros that work with any pointer type
- **Type-safe macros** — for type casting and operations
- **Unit testing** — with the Unity C testing framework - **Unit testing** — with the Unity C testing framework
## ✨ Features ## ✨ Features
- **Dynamic resizing** — Automatically grows as elements are added - **Header-only** — just include `dynamic_array.h`, no compilation step needed
- **Type-safe operations** — Macros for working with typed elements - **Dynamic resizing** — automatically grows as elements are added
- **Simple API** — Easy-to-use functions for common operations - **Type-safe** — macros operate on typed pointers; direct indexing is fully typed
- **Simple API** — a small set of macros for common operations
## 📁 Project Structure ## 📁 Project Structure
``` ```
test-meson/ dynamic_array/
├── src/ ├── src/
│ ├── dynamic_array.c # Implementation │ ├── dynamic_array.h # Header-only implementation (public API)
│ ├── dynamic_array.h # Public API header
│ ├── test_dynamic_array.c # Unit tests │ ├── test_dynamic_array.c # Unit tests
│ └── CMakeLists.txt # Build configuration │ └── CMakeLists.txt # Build configuration
├── submodules/ ├── submodules/
@@ -33,6 +34,7 @@ test-meson/
├── Makefile # Build automation ├── Makefile # Build automation
└── README.md # This file └── README.md # This file
``` ```
## 🔧 Prerequisites ## 🔧 Prerequisites
**Linux-only project** **Linux-only project**
@@ -41,6 +43,7 @@ test-meson/
- **C compiler** (GCC recommended, Clang supported) - **C compiler** (GCC recommended, Clang supported)
- **Make** (optional, but recommended) - **Make** (optional, but recommended)
- **build-essential** (on Ubuntu/Debian): `sudo apt-get install build-essential` - **build-essential** (on Ubuntu/Debian): `sudo apt-get install build-essential`
## 🔨 Building ## 🔨 Building
### Using the Makefile (Recommended) ### Using the Makefile (Recommended)
@@ -63,6 +66,7 @@ ctest --output-on-failure
cmake --install . cmake --install .
cd .. && rm -rf build cd .. && rm -rf build
``` ```
## 💡 Usage ## 💡 Usage
### Including the Library ### Including the Library
@@ -70,72 +74,70 @@ cd .. && rm -rf build
```c ```c
#include "dynamic_array.h" #include "dynamic_array.h"
// Create an array of integers // Create a typed array (works with any pointer type)
ArrayCreateOptions opts = { int *arr = NULL;
.initial_size = 10, array_create(arr);
.element_size = sizeof(int)
};
Array *my_array = array_create(&opts);
// Add elements // Add elements
int value = 42; array_push_value(arr, 10);
array_set_value(my_array, 0, &value); array_push_value(arr, 20);
array_push_value(arr, 30);
// Retrieve elements // Access elements directly via indexing
int *retrieved = (int*)array_get_value(my_array, 0); int first = arr[0]; // 10
// Using type-safe macros // Remove the last element
int result = array_set_value_as(int, my_array, 1, 100); array_pop(arr);
// Get size and capacity // Inspect size and capacity via the header
size_t size = array_get_size(my_array); const ArrayHeader *header = array_get_header(arr);
size_t capacity = array_get_capacity(my_array); size_t size = header->size; // current number of elements
size_t capacity = header->capacity; // allocated capacity
// Cleanup // Cleanup
array_deconstructor(&my_array); array_destroy(arr); // frees memory and sets arr to NULL
``` ```
## 📖 API Reference ## 📖 API Reference
### Structures ### Structures
#### `Array` #### `ArrayHeader`
Stored immediately before the array data in memory. Retrieve it with `array_get_header`.
```c ```c
typedef struct { 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 size; // Current number of elements
size_t capacity; // Allocated capacity size_t capacity; // Allocated capacity
} Array; } ArrayHeader;
``` ```
#### `ArrayCreateOptions` Memory layout:
```c
typedef struct {
int initial_size; // Initial capacity
size_t element_size; // Size of each element type
} ArrayCreateOptions;
``` ```
[ ArrayHeader | elem 0 | elem 1 | ... ]
### Functions
pointer returned by array_create (and all macros)
| 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 |
### Macros ### Macros
| Macro | Description | | Macro | Description |
|-------|-------------| |-------|-------------|
| `array_get_value_as(type, arr, idx)` | Type-safe retrieval of elements | | `array_create(arr)` | Allocates a new array; sets `arr` to point to the first element |
| `array_set_value_as(type, arr, idx, value)` | Type-safe setting of elements (with type checking) | | `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 ## ✅ Testing
Tests are written using the [Unity](http://www.throwtheswitch.org/unity) C testing framework. Tests are written using the [Unity](http://www.throwtheswitch.org/unity) C testing framework.
@@ -149,6 +151,7 @@ Or directly with ctest:
```bash ```bash
cd build && ctest --output-on-failure cd build && ctest --output-on-failure
``` ```
## 📦 Installation ## 📦 Installation
### Default Installation ### Default Installation
@@ -158,7 +161,6 @@ make install
``` ```
This installs to `~/.local/bin/dynamic_array/`: This installs to `~/.local/bin/dynamic_array/`:
- **Library:** `lib/libdynamic_array.a`
- **Header:** `include/dynamic_array.h` - **Header:** `include/dynamic_array.h`
### Custom Installation Directory ### Custom Installation Directory
@@ -173,20 +175,26 @@ Or set it as an environment variable:
export INSTALL_PREFIX=$HOME/.local export INSTALL_PREFIX=$HOME/.local
make install make install
``` ```
## ⚠️ Known Issues & Limitations ## ⚠️ 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) - ⚠️ Simple reallocation strategy (not optimized for performance)
- ⚠️ Not thread-safe - ⚠️ Not thread-safe
- ⚠️ Limited error handling - ⚠️ `realloc` failure is not propagated to the caller
- ⚠️ Educational purpose only — use established libraries for production - ⚠️ Educational purpose only — use established libraries for production
## 🚀 Future Improvements ## 🚀 Future Improvements
- [ ] Return value from `array_pop`
- [ ] Propagate allocation failures
- [ ] Add more comprehensive error handling - [ ] Add more comprehensive error handling
- [ ] Implement shrinking functionality - [ ] Implement shrinking / `array_reserve`
- [ ] Add iterator support - [ ] Add iterator support
- [ ] Optimize memory allocation strategy - [ ] Optimize memory allocation strategy
- [ ] Add more test coverage - [ ] Add more test coverage
## 📄 License ## 📄 License
This project is for educational purposes. This project is for educational purposes.