Skip to content

haseeb-heaven/stb_vector

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

stb_vector

Version License C Standard C++

stb_vector is a single-header, type-safe, generic dynamic array library for C (also compatible with C++). Inspired by the stb libraries philosophy, it provides easy-to-use dynamic arrays similar to C++ std::vector with modern safety features and zero external dependencies.


πŸ“‹ Table of Contents


✨ Features

  • 🎯 Type-Safe: Generic programming with compile-time type checking
  • πŸ“¦ Single Header: Just drop stb_vector.h into your project
  • πŸ›‘οΈ Memory Safe: Bounds checking, use-after-free detection, allocation failure handling
  • ⚑ Fast: O(1) amortized push, cache-friendly contiguous storage
  • πŸ”§ Easy to Use: Clean API similar to C++ vectors
  • 🎨 Exception Handling: Try/catch style error handling using setjmp/longjmp
  • 🧡 Thread-Aware: Thread-local error contexts for multi-threaded environments
  • πŸ”“ No Dependencies: Pure C with standard library only
  • 🌐 Portable: Works on Windows, Linux, macOS, Unix (32/64-bit)
  • πŸ”„ C++ Compatible: Works seamlessly in C++ projects

πŸ€” Why stb_vector?

The Problem

C doesn't have built-in dynamic arrays. Traditional solutions involve:

  • Manual memory management - Error-prone malloc/realloc/free
  • Unsafe macros - Type-unsafe, hard to debug
  • Complex libraries - Heavy dependencies, steep learning curve

The Solution

stb_vector brings C++-style vectors to C with:

  • βœ… Type safety without templates
  • βœ… Automatic memory management
  • βœ… Familiar API (like std::vector)
  • βœ… Single-header simplicity
  • βœ… Production-ready error handling

πŸš€ Quick Start

#define STB_VECTOR_IMPLEMENTATION
#include "stb_vector.h"
#include <stdio.h>

int main(void) {
    // Create a new integer vector
    Vector(int) *vec = vector_new(int);

    // Add elements
    $(vec)->push_back(10);
    $(vec)->push_back(20);
    $(vec)->push_back(30);

    // Access elements
    printf("Size: %zu\n", $(vec)->size());
    printf("First: %d\n", $(vec)->front());
    printf("Last: %d\n", $(vec)->back());

    // Iterate
    for (size_t i = 0; i < $(vec)->size(); ++i) {
        printf("%d ", $(vec)->get(i));
    }
    printf("\n");

    // Cleanup
    $(vec)->destroy();
    free(vec);

    return 0;
}

Output:

Size: 3
First: 10
Last: 30
10 20 30

πŸ“₯ Installation

Method 1: Copy Header (Recommended)

  1. Download stb_vector.h
  2. Copy it to your project directory
  3. Include it in ONE C file with the implementation:
#define STB_VECTOR_IMPLEMENTATION
#include "stb_vector.h"
  1. In other files, just include without the define:
#include "stb_vector.h"

Method 2: CMake

git clone https://github.com/haseeb-heaven/stb_vector.git
cd stb_vector
mkdir build && cd build
cmake ..
make

πŸ“– API Reference

Creation

Vector(T) *vec = vector_new(T);              // Empty vector
Vector(T) *vec = vector_new(T, 10);          // Pre-sized (10 elements, zero-initialized)
Vector(T) *vec = vector_new(T, 10, value);   // Pre-filled (10 elements, all = value)

Modification

Function Description Complexity
$(vec)->push_back(value) Add element to end O(1) amortized
$(vec)->pop_back() Remove last element O(1)
$(vec)->insert(idx, value) Insert at position O(n)
$(vec)->erase(idx) Remove at position O(n)
$(vec)->set(idx, value) Set element at index O(1)
$(vec)->resize(new_size) Change size O(n) if growing
$(vec)->reserve(capacity) Reserve capacity O(n) if growing
$(vec)->clear() Remove all elements O(1)

Access (with bounds checking)

Function Description Complexity
$(vec)->get(idx) Get element at index O(1)
$(vec)->at(idx) Alias for get() O(1)
$(vec)->front() Get first element O(1)
$(vec)->back() Get last element O(1)
$(vec)->data_ptr() Get raw pointer to data O(1)

Information

Function Description
$(vec)->size() Current number of elements
$(vec)->capacity() Allocated capacity
$(vec)->empty() Check if empty
$(vec)->max_size() Maximum possible size

Optimization

Function Description
$(vec)->shrink_to_fit() Release unused memory
$(vec)->swap(other_vec) Swap with another vector (O(1))

Cleanup

$(vec)->destroy();  // Free internal data
free(vec);          // Free the struct itself

πŸ”¨ Building Examples

Using CMake

mkdir build && cd build
cmake ..
make

# Run examples
./examples/example_c
./examples/example_cpp

# Run tests
./tests/test_vector

Manual Compilation

C Example:

gcc -o example_c examples/example_c.c -I. -std=c99
./example_c

C++ Example:

g++ -o example_cpp examples/example_cpp.cpp -I. -std=c++11
./example_cpp

πŸ§ͺ Running Tests

cd build
make
./tests/test_vector

Tests cover:

  • βœ… Creation and destruction
  • βœ… Push/pop operations
  • βœ… Insert/erase
  • βœ… Resizing and reserving
  • βœ… Bounds checking
  • βœ… Error handling
  • βœ… Edge cases (empty vector, large sizes)
  • βœ… Memory leak detection

πŸ†š Comparison with C++ std::vector

stb_vector is designed to be conceptually similar to C++ std::vector, making it intuitive for C++ developers working in C.

Similarities

Feature std::vector stb_vector
Dynamic array βœ… βœ…
Type-safe βœ… βœ…
Automatic memory management βœ… βœ…
Bounds checking (at) βœ… βœ…
push_back, pop_back βœ… βœ…
insert, erase βœ… βœ…
size, capacity βœ… βœ…
resize, reserve βœ… βœ…
front, back βœ… βœ…
clear, empty βœ… βœ…
shrink_to_fit βœ… βœ…
swap βœ… βœ…

Key Differences

Aspect std::vector stb_vector
Language C++ C (C++ compatible)
Implementation Template Macro-generated
Element access vec[i] or vec.at(i) $(vec)->get(i)
Iterators βœ… (full iterator support) ❌ (use indices)
Range-based for βœ… ❌ (use index loop)
Move semantics βœ… (C++11+) N/A
Exception handling C++ exceptions setjmp/longjmp
Context binding Automatic $(vec) macro

Example Comparison

C++ std::vector:

std::vector<int> vec;
vec.push_back(10);
vec.push_back(20);
std::cout << vec[0] << std::endl;
for (int x : vec) {
    std::cout << x << " ";
}

C++ stb_vector:

Vector(int) *vec = vector_new(int);
$(vec)->push_back(10);
$(vec)->push_back(20);
std::cout << $(vec)->get(0) << std::endl;
for (size_t index = 0; index < $(vec)->size(); ++index) {
    std::cout << $(vec)->get(index) << " ";
}
$(vec)->destroy();
free(vec);

⚑ Performance

Time Complexity

Operation Complexity Notes
push_back O(1)* *Amortized (2x growth factor)
pop_back O(1)
get/set O(1) Direct array access
insert O(n) Shifts elements
erase O(n) Shifts elements
resize O(n) Only if growing
clear O(1) Just resets size

Space Complexity

  • Per-vector overhead: ~40 bytes (struct metadata)
  • Growth strategy: Exponential (2x doubling)
  • Memory layout: Contiguous array (cache-friendly)

Benchmarks

On a typical modern CPU (x86_64):

  • 1M push_back operations: ~5-10ms
  • Random access (1M gets): ~2-3ms
  • Resize to 1M elements: ~5-8ms

(Actual performance depends on hardware, compiler optimizations, and data types)


πŸ›‘οΈ Safety Features

1. Bounds Checking

All access operations validate indices:

Vector(int) *vec = vector_new(int);
$(vec)->get(10);  // ERROR: Out of bounds

2. Use-After-Free Detection

Magic number validation:

$(vec)->destroy();
$(vec)->push_back(10);  // ERROR: Invalid vector (magic number check fails)

3. Allocation Failure Handling

Graceful error reporting:

stb_try(vec) {
    $(vec)->reserve(SIZE_MAX);  // Will fail
} stb_catch {
    printf("Error: %s\n", vec->error.message);
}

4. Exception-Style Error Handling

stb_try(vec) {
    $(vec)->push_back(10);
    $(vec)->get(100);  // Throws exception
    // Code below doesn't execute
} stb_catch {
    printf("Caught: %s\n", vec->error.message);
}

🧡 Thread Safety

βœ… Safe

  • Different vectors in different threads: Fully safe
  • Thread-local error contexts: Each thread has its own error state

❌ Not Safe

  • Sharing same vector across threads: Requires external synchronization (mutex)

Example:

// Thread 1
Vector(int) *vec1 = vector_new(int);
$(vec1)->push_back(10);  // βœ… Safe

// Thread 2
Vector(int) *vec2 = vector_new(int);
$(vec2)->push_back(20);  // βœ… Safe

// Thread 1 and 2 accessing vec1
// ❌ NOT SAFE without mutex

🎨 Custom Types

You can use stb_vector with custom types:

typedef struct {
    int x;
    int y;
} Point;

// Declare vector for Point type
DECLARE_VECTOR(Point)

// Usage
Vector(Point) *points = vector_new(Point);
Point p = {10, 20};
$(points)->push_back(p);

Built-in types: int, float, double, char, long


βš™οΈ Configuration

You can customize memory allocation:

#define STB_VECTOR_MALLOC(sz, ctx)       my_malloc(sz)
#define STB_VECTOR_REALLOC(ptr, sz, ctx) my_realloc(ptr, sz)
#define STB_VECTOR_FREE(ptr, ctx)        my_free(ptr)

#define STB_VECTOR_IMPLEMENTATION
#include "stb_vector.h"

Other configuration:

  • STB_VECTOR_INITIAL_CAPACITY (default: 1)
  • STB_VECTOR_GROWTH_FACTOR (default: 2)

πŸ“„ License

This software is dual-licensed. Choose whichever you prefer:

Option A: MIT License

Copyright (c) 2025 Haseeb Mir

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED.

Option B: Public Domain

This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software.


🀝 Contributing

Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.

Development

git clone https://github.com/haseeb-heaven/stb_vector.git
cd stb_vector
mkdir build && cd build
cmake ..
make
make test

πŸ“š Documentation


πŸ™ Acknowledgments

Inspired by:


πŸ“¬ Contact

Author: Haseeb Mir
Version: 1.0
Repository: https://github.com/haseeb-heaven/stb_vector


Made with ❀️ for the C community

About

single-header, type-safe, generic dynamic array library for C

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published