Vector Container

Certainly! Below is a well-structured documentation on the Vector Container in C:


📚 Vector Container in C - Documentation

✅ Introduction

In C++, the std::vector is a dynamic array container from the Standard Template Library (STL) that automatically manages memory as elements are added or removed.

However, C has no built-in vector container. But similar functionality can be manually implemented using dynamic memory allocation (malloc/realloc).

This documentation explains how a vector container works conceptually and how to implement it in C.


✅ What is a Vector?

A vector is:

  • A dynamic array that grows or shrinks in size automatically.
  • Stores elements of the same data type.
  • Provides random access to elements.

Key Operations: ✔ Add an element (push back)

✔ Remove the last element (pop back)

✔ Access an element by index

✔ Resize capacity dynamically


✅ Structure of a Vector Container in C

typedef struct {
    int *data;      // Pointer to the array of elements
    int size;       // Current number of elements
    int capacity;   // Maximum number of elements before resizing
} Vector;

✅ Basic Vector Functions

Here’s a simple implementation of a vector-like container for integers:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    int *data;
    int size;
    int capacity;
} Vector;

// Initialize vector
void initVector(Vector *vec) {
    vec->size = 0;
    vec->capacity = 2; // Initial capacity
    vec->data = (int *)malloc(vec->capacity * sizeof(int));
}

// Add element to vector
void pushBack(Vector *vec, int value) {
    if (vec->size == vec->capacity) {
        vec->capacity *= 2;  // Double the capacity
        vec->data = (int *)realloc(vec->data, vec->capacity * sizeof(int));
    }
    vec->data[vec->size++] = value;
}

// Remove last element
void popBack(Vector *vec) {
    if (vec->size > 0) {
        vec->size--;
    }
}

// Get element at index
int get(Vector *vec, int index) {
    if (index >= 0 && index < vec->size) {
        return vec->data[index];
    }
    printf("Index out of bounds\n");
    return -1;  // Error value
}

// Free the vector
void freeVector(Vector *vec) {
    free(vec->data);
}

✅ Usage Example

int main() {
    Vector vec;
    initVector(&vec);

    pushBack(&vec, 10);
    pushBack(&vec, 20);
    pushBack(&vec, 30);

    printf("Element at index 1: %d\n", get(&vec, 1));  // Output: 20
    printf("Vector size: %d\n", vec.size);

    popBack(&vec);
    printf("Vector size after pop: %d\n", vec.size);

    freeVector(&vec);
    return 0;
}

Output:

Element at index 1: 20
Vector size: 3
Vector size after pop: 2

✅ Advantages of Vector Container

✔ Dynamic resizing eliminates the need to manage array sizes manually.

✔ Provides random access similar to arrays.

✔ Easy to implement common operations (push, pop, access).


✅ Limitations

⚠ No type safety if using void * for generic types (need to handle casting).

⚠ Manual memory management (malloc, free) can lead to leaks if not handled properly.

⚠ Slower than static arrays in some cases due to frequent reallocations.


✅ Extending Vector for Generic Types

For generic behavior:

typedef struct {
    void *data;
    size_t elem_size;
    int size;
    int capacity;
} GenericVector;

You’ll handle memory with memcpy and void*.


✅ Conclusion

While C lacks a built-in vector container, dynamic arrays (vectors) can be efficiently implemented using structs, malloc, and realloc. Mastering this helps create flexible data structures like lists, stacks, and queues in C.


✅ Further Enhancements / Next Steps

  • Implement insert(), erase(), and resize() functions.
  • Use void pointers to handle generic data types.
  • Add error handling and bounds checking.
  • Explore third-party libraries (like glib) that offer dynamic array implementations.

Would you like an example of a generic vector (for any data type) next or should I generate a header file and source file for a complete reusable module?

Did this answer your question?
😞
😐
🤩