Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/l-a-marchetti/maestro
A C Dynamic Array Library
https://github.com/l-a-marchetti/maestro
Last synced: about 1 month ago
JSON representation
A C Dynamic Array Library
- Host: GitHub
- URL: https://github.com/l-a-marchetti/maestro
- Owner: L-A-Marchetti
- License: mit
- Created: 2024-11-13T17:11:13.000Z (about 2 months ago)
- Default Branch: main
- Last Pushed: 2024-11-24T09:42:20.000Z (about 2 months ago)
- Last Synced: 2024-11-24T10:26:58.562Z (about 2 months ago)
- Language: C
- Homepage:
- Size: 32.2 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Maestro - A C Dynamic Array Library
# Table of Contents
1. [Description](#description)
- [Key Features](#key-features)
- [Memory Management](#memory-management)3. [Maestro's Internal Logic](#maestros-internal-logic)
- [Internal Mechanism](#internal-mechanism)
- [Advantages](#advantages)
- [Disadvantages](#disadvantages)4. [Installation and Usage](#installation-and-usage)
- [Installation](#installation)
- [Including in Your Project](#including-in-your-project)
- [Compilation](#compilation)5. [Functions Guide](#functions-guide)
- [maestro_new](#maestro_new)
- [push_back](#push_back)
- [pop_back](#pop_back)
- [insert](#insert)
- [erase](#erase)
- [destroy](#destroy)6. [Complete Example](#complete-example)
# Description
Maestro is a lightweight and efficient C library that implements a generic dynamic array data structure. It provides an elegant solution for managing collections of elements of any data type, offering flexible and efficient array manipulation in memory.
## Key Features
- **Type Agnostic**: Works with any data type through void* pointers
- **Dynamic Memory Management**: Automatic memory allocation and reallocation as needed
- **Intuitive API**: Clean and consistent interface for collection manipulation
- **Comprehensive Operations**: Support for fundamental operations like insertion, deletion, and appending## Memory Management
Maestro handles all memory management internally, including:
- Initial allocation during creation
- Dynamic resizing when elements are added
- Proper cleanup when elements are removed
- Complete deallocation during destructionThis automatic memory management helps prevent memory leaks while maintaining optimal performance.
# Maestro's Internal Logic
Maestro implements a contiguous dynamic array using a void pointer (`void* data`) as its primary storage mechanism. This approach allows for storing any data type while maintaining memory efficiency and direct access capabilities.
## Internal Mechanism
The library stores elements in contiguous memory locations, which means all elements are placed next to each other in memory. When you store elements in `data`, they are placed sequentially, with each element occupying `element_size` bytes. To access an element at position `i`, Maestro performs pointer arithmetic: `data + (i * element_size)`.
### Advantages:
- **Cache Efficiency**: Contiguous storage means better cache utilization and faster memory access
- **Type Flexibility**: Using `void*` allows storing any data type
- **Direct Access**: Fast access time to any element using pointer arithmetic### Disadvantages:
- **Reallocation Cost**: Adding elements may require reallocating and copying the entire array
- **Type Safety**: Using `void*` means type checking must be handled by the user
- **Memory Limitations**: Requires a single contiguous block of memory# Installation and Usage
## Installation
Maestro can be easily installed by downloading the [last version](https://github.com/L-A-Marchetti/maestro/releases) and using the provided installation script:
```bash
./install.sh
```This script will:
- Copy the header file to the appropriate system include directory
- Install the static library `libmaestro.a` to the system library path
- Set up the necessary permissions## Usage
### Including in Your Project
To use Maestro in your C project, include the header file:
```c
#include
```### Compilation
When compiling your project, you need to link against the Maestro library.
If you're using a Makefile, add the library flag:
```makefile
LDFLAGS += -lmaestro
```Or when compiling directly with gcc:
```bash
gcc your_program.c -o your_program -lmaestro
```This will link your program with the Maestro library, giving you access to all its dynamic array functionality.
# Functions Guide
First, let's define our structure:
```c
typedef struct {
int id;
double value;
const char* name;
} Item;
```## `maestro_new`
Creates a new dynamic array with the specified element size.
```c
// Create an array for our Items
maestro* items = maestro_new(sizeof(Item));
```## `push_back`
Adds a new element at the end of the array. The array will automatically resize if needed.
```c
Item new_item = {1, 3.14, "First"};
items->push_back(items, &new_item);
```## `pop_back`
Removes the last element from the array. If the array becomes empty, it frees the memory.
```c
items->pop_back(items); // Removes the last Item
```## `insert`
Inserts a new element at the specified position, shifting all subsequent elements one position forward.
```c
Item insert_item = {2, 2.71, "Second"};
items->insert(items, 1, &insert_item); // Inserts at position 1
```## `erase`
Removes an element at the specified position, shifting all subsequent elements one position backward.
```c
items->erase(items, 0); // Removes Item at position 0
```## `destroy`
Frees all allocated memory associated with the array and the array itself.
```c
items->destroy(items); // Cleans up the array
```# Complete Example
```c
#includetypedef struct {
int id;
double value;
const char* name;
} Item;int main()
{
// Create the array
maestro* items = maestro_new(sizeof(Item));// Create some Items
Item a = {1, 1.1, "First"};
Item b = {2, 2.2, "Second"};
Item c = {3, 3.3, "Third"};
Item d = {4, 4.4, "Fourth"};// Add elements
items->push_back(items, &a); // [{1, 1.1, "First"}]
items->push_back(items, &b); // [{1, 1.1, "First"}, {2, 2.2, "Second"}]
items->push_back(items, &c); // [{1, 1.1, "First"}, {2, 2.2, "Second"}, {3, 3.3, "Third"}]// Remove last element
items->pop_back(items); // [{1, 1.1, "First"}, {2, 2.2, "Second"}]// Insert at position 1
items->insert(items, 1, &c); // [{1, 1.1, "First"}, {3, 3.3, "Third"}, {2, 2.2, "Second"}]// Add another element
items->push_back(items, &d); // [{1, 1.1, "First"}, {3, 3.3, "Third"}, {2, 2.2, "Second"}, {4, 4.4, "Fourth"}]// Erase element at position 2
items->erase(items, 2); // [{1, 1.1, "First"}, {3, 3.3, "Third"}, {4, 4.4, "Fourth"}]// Display array contents
for (size_t i = 0; i < items->length; i++) {
Item current = ((Item*)items->data)[i];
printf("Id: %d, Value: %.1f, Name: %s\n",
current.id, current.value, current.name);
}// Clean up
items->destroy(items);
return 0;
}
```