Vector 0.0.2
Loading...
Searching...
No Matches
📘 Guide

🔨 Creating a vector

In this section we'll discuss creation of the vector.
Based on Example file.

⚙️ Default options

vector_t *vector = vector_create(.element_size = sizeof(int));
#define vector_create(...)
Vector constructor.
Definition vector.h:162
Vector control structure type.
Definition vector.c:24

⚙️ Custom options

vector_t *vector = vector_create (
.element_size = sizeof(float),
.initial_cap = 100
);
Note
Extension and Custom allocator options will be discussed later.


⚙️ No macro wrapper

You can avoid macro wrapper with default values if you know what you are doing.
Just create opts on stack
and pass by reference into a vector_create_ function directly:

vector_opts_t opts = {.element_size = sizeof(int)};
Vector options.
Definition vector.h:52
size_t element_size
Size of the underling element type.
Definition vector.h:56
vector_t *vector = vector_create_(&opts);
vector_t * vector_create_(const vector_opts_t *const opts)
Vector contructor.
Definition vector.c:82


⿻ Clone an existing vector

With vector_clone you are able to produce exact copy of an existing vector.

vector_t *clone = vector_clone(vector);
vector_t * vector_clone(const vector_t *const vector)
Duplicates a vector.
Definition vector.c:119


❗Error handling

Check that vector value is NULL, then resolve allocation error. If you got none resolution choises, perform gracefull program termination. See following example, print error and exit abnormally.

if (!vector)
{
perror("vector_create");
abort();
}


🧨 Deallocating a vector

Prevent memory leaks by deallocation resources, when they not needed anymore!

vector_destroy(vector);
void vector_destroy(vector_t *const vector)
Deallocates vector.
Definition vector.c:112
Attention
Always remember to deallocate vector created with vector_create or vector_clone !



⬆️ Extending a vector

In this section we'll discuss an extension points of the vector

⚙️ Allocate extended header

It is possible to reserve space to store derived class data
in a memory allocated by underlying vector.

Define a structure ext_t that will be peallocated right after vector_t and allocator region if present:

typedef struct
{
size_t meta;
// ...
// ...
// ...
}
ext_t;

Create vector specifying vector_opts_t::ext_header_size to reserve space for ext_t.

vector_t *vector = vector_create (
.ext_header_size = sizeof(ext_t),
.element_size = sizeof(long)
);

Initialize extended header:

ext_t *header = vector_get_ext_header(vector);
*header = (ext_t) {0};
void * vector_get_ext_header(const vector_t *const vector)
Provides a location where user can put a header for the derived class.
Definition vector.c:162


❗Customize resize error

Resize function takes additional parameter error indicating an error code that is going to be returned from resize when allocation error occures. This allows derived classes to provide custom error code that is not in vector_status_t and/or if they need different error codes depending on context they call resize from.

See also
vector_resize

⚙️ Override default allocator

Define a structure of the allocator region:
ALIGNED macro serves as constructor for temporary reference to an alloc_t.

#define ALIGNED(bytes) &(alloc_t){.alignment = bytes}
#if defined _WIN32 || defined __CYGWIN__
#define aligned_alloc(alignment, size) _aligned_malloc(size, alignment)
#endif
// #ifdef __linux__
// static_assert(0)
// #endif
typedef struct alloc
{
size_t alignment;
size_t last_size;
}
alloc_t;

Create vector by providing alloc_opts_t :

vector_t *aligned_vector = vector_create (
.element_size = sizeof(int),
.size = sizeof(alloc_t),
.data = ALIGNED(MAX_ALIGNMENT),
),
);
#define alloc_opts(...)
Use this macro to define allocator opts in vector_opts_t.
Definition vector.h:153

Implement vector_alloc, vector_realloc, and vector_free functions
Functions can be implemented in external translation unit and then linked:

void *vector_alloc(const size_t alloc_size, void *const param)
{
assert(param);
alloc_t* alloc = (alloc_t*)param;
return aligned_alloc(alloc->alignment, alloc_size);
void * vector_alloc(const size_t alloc_size, void *const param)
Allocates memory chunk of alloc_size.
}


void *vector_realloc(void *const ptr, size_t alloc_size, void *const param)
{
assert(ptr);
assert(alloc_size > 0);
assert(param);
alloc_t *alloc = (alloc_t*)param;
if (alloc_size == alloc->last_size)
{
return ptr;
void * vector_realloc(void *const ptr, size_t alloc_size, void *const param)
Reallocates already allocated memory chunk in order to change allocation size.
}


void vector_free(void *const ptr, void *const param)
{
(void) param;
free(ptr);
}
void vector_free(void *const ptr, void *const param)
Free allocation that was previously allocated.