Array
Header File
#include "mln_array.h"
Module
array
Functions/Macros
mln_array_init
int mln_array_init(mln_array_t *arr, array_free free, mln_size_t size, mln_size_t nalloc);
typedef void (*array_free)(void *);
Description: Initialize a given array arr. The parameter meanings are as follows:
arrarray object.freeis a function pointer used to release resources of array elements.sizeis the size in bytes of a single array element.nallocis the initial array length, and subsequent array expansion is expanded by twice the number of elements allocated in the current array.
Return value: Returns 0 on success, otherwise returns -1
mln_array_pool_init
int mln_array_pool_init(mln_array_t *arr, array_free free, mln_size_t size, mln_size_t nalloc,
void *pool, array_pool_alloc_handler pool_alloc, array_pool_free_handler pool_free);
typedef void *(*array_pool_alloc_handler)(void *, mln_size_t);
typedef void (*array_pool_free_handler)(void *);
typedef void (*array_free)(void *);
Description: Initialize a given array arr using memory pool memory. The parameter meanings are as follows:
arrarray object.freeis a function pointer used to release resources of array elements.sizeis the size in bytes of a single array element.nallocis the initial array length, and subsequent array expansion is expanded by twice the number of elements allocated in the current array.poolis a custom memory pool structure pointer.pool_allocis a custom memory pool allocation function pointer.pool_freeis a custom memory pool release function pointer.
Return value: Returns 0 on success, otherwise returns -1
mln_array_new
mln_array_t *mln_array_new(array_free free, mln_size_t size, mln_size_t nalloc);
Description: Create and initialize an array based on the given parameters.
Return value: Returns array pointer if successful, otherwise returns NULL
mln_array_pool_new
mln_array_t *mln_array_pool_new(array_free free, mln_size_t size, mln_size_t nalloc, void *pool,
array_pool_alloc_handler pool_alloc, array_pool_free_handler pool_free);
Description: Creates and initializes an array using memory pool memory according to the given parameters.
Return value: Returns array pointer if successful, otherwise returns NULL
mln_array_destroy
void mln_array_destroy(mln_array_t *arr);
Description: Free the memory of all elements of the specified array arr.
Return value: None
mln_array_free
void mln_array_free(mln_array_t *arr);
Description: Release the memory of all elements of the specified array arr, and release the memory of the array itself.
Return value: None
mln_array_reset
void mln_array_reset(mln_array_t *arr);
Description: Release the elements in arr, and set the length of the array to 0, but do not release the array structure.
Return value: None
mln_array_push
void *mln_array_push(mln_array_t *arr);
Description: Append an element to the array and return the memory address of the element.
Return value: return element address if successful, otherwise return NULL
mln_array_pushn
void *mln_array_pushn(mln_array_t *arr, mln_size_t n);
Description: Append n elements to the array, and return the first memory address of these elements.
Return value: return element address if successful, otherwise return NULL
mln_array_pop
void mln_array_pop(mln_array_t *arr);
Description: Remove and release the last element of the array. If the array is empty or arr is NULL, this is a no-op.
Return value: None
mln_array_grow
int mln_array_grow(mln_array_t *arr, mln_size_t n);
Description: Ensure the array has enough capacity for at least n additional elements beyond the current count. The array doubles its allocated size until the required capacity is met. For non-pool arrays, realloc is used for efficient in-place growth.
Return value: Returns 0 on success, otherwise returns -1
mln_array_elts
mln_array_elts(arr);
Description: Get the starting address of all elements of the array.
Return value: element starting address
mln_array_nelts
mln_array_nelts(arr);
Description: Get the number of elements in the array.
Return value: number of elements
MLN_ARRAY_PUSH
MLN_ARRAY_PUSH(arr, ret_ptr);
Description: Inline macro version of mln_array_push. Pushes one element onto the array and assigns its address to ret_ptr. On the fast path (no reallocation needed) this avoids function call overhead entirely. If allocation fails, ret_ptr is set to NULL.
arrpointer tomln_array_t.ret_ptravoid *(or typed pointer) lvalue that receives the element address.
Return value: None (result is stored in ret_ptr)
MLN_ARRAY_PUSHN
MLN_ARRAY_PUSHN(arr, n, ret_ptr);
Description: Inline macro version of mln_array_pushn. Pushes n elements onto the array and assigns the first element's address to ret_ptr. If allocation fails, ret_ptr is set to NULL.
arrpointer tomln_array_t.nnumber of elements to push.ret_ptravoid *(or typed pointer) lvalue that receives the starting address.
Return value: None (result is stored in ret_ptr)
MLN_ARRAY_POP
MLN_ARRAY_POP(arr);
Description: Inline macro version of mln_array_pop. Removes the last element and invokes the free callback if set. If the array is empty or NULL, this is a no-op.
arrpointer tomln_array_t.
Return value: None
Example
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "mln_array.h"
static int free_count = 0;
typedef struct {
int i1;
int i2;
} test_t;
static void test_free(void *data)
{
(void)data;
++free_count;
}
static void *pool_alloc(void *pool, mln_size_t size)
{
(void)pool;
return malloc(size);
}
static void pool_dealloc(void *ptr)
{
free(ptr);
}
int main(void)
{
test_t *t;
mln_size_t i;
mln_array_t arr;
/* --- init / push / pushn / elts / nelts / destroy --- */
assert(mln_array_init(&arr, NULL, sizeof(test_t), 1) == 0);
t = (test_t *)mln_array_push(&arr);
assert(t != NULL);
t->i1 = 0;
t = (test_t *)mln_array_pushn(&arr, 9);
assert(t != NULL);
for (i = 0; i < 9; ++i)
t[i].i1 = i + 1;
for (t = (test_t *)mln_array_elts(&arr), i = 0; i < mln_array_nelts(&arr); ++i)
printf("%d\n", t[i].i1);
mln_array_destroy(&arr);
/* --- new / free with free callback --- */
free_count = 0;
mln_array_t *a = mln_array_new(test_free, sizeof(test_t), 4);
assert(a != NULL);
for (i = 0; i < 3; ++i) {
t = (test_t *)mln_array_push(a);
assert(t != NULL);
t->i1 = (int)i;
}
mln_array_free(a);
assert(free_count == 3);
/* --- pop --- */
free_count = 0;
assert(mln_array_init(&arr, test_free, sizeof(test_t), 4) == 0);
t = (test_t *)mln_array_push(&arr);
t->i1 = 1;
t = (test_t *)mln_array_push(&arr);
t->i1 = 2;
mln_array_pop(&arr);
assert(mln_array_nelts(&arr) == 1 && free_count == 1);
mln_array_destroy(&arr);
/* --- reset --- */
free_count = 0;
assert(mln_array_init(&arr, test_free, sizeof(test_t), 4) == 0);
for (i = 0; i < 5; ++i) {
t = (test_t *)mln_array_push(&arr);
t->i1 = (int)i;
}
mln_array_reset(&arr);
assert(mln_array_nelts(&arr) == 0 && free_count == 5);
mln_array_destroy(&arr);
/* --- grow --- */
assert(mln_array_init(&arr, NULL, sizeof(test_t), 0) == 0);
assert(mln_array_grow(&arr, 8) == 0);
t = (test_t *)mln_array_push(&arr);
assert(t != NULL);
mln_array_destroy(&arr);
/* --- inline macros: MLN_ARRAY_PUSH / MLN_ARRAY_PUSHN / MLN_ARRAY_POP --- */
assert(mln_array_init(&arr, NULL, sizeof(test_t), 2) == 0);
for (i = 0; i < 10; ++i) {
MLN_ARRAY_PUSH(&arr, t);
assert(t != NULL);
t->i1 = (int)i;
}
MLN_ARRAY_PUSHN(&arr, 5, t);
assert(t != NULL);
assert(mln_array_nelts(&arr) == 15);
MLN_ARRAY_POP(&arr);
assert(mln_array_nelts(&arr) == 14);
mln_array_destroy(&arr);
/* --- pool_init / pool_new --- */
int dummy_pool = 0;
assert(mln_array_pool_init(&arr, NULL, sizeof(test_t), 4,
&dummy_pool, pool_alloc, pool_dealloc) == 0);
t = (test_t *)mln_array_push(&arr);
assert(t != NULL);
t->i1 = 77;
mln_array_destroy(&arr);
mln_array_t *pa = mln_array_pool_new(NULL, sizeof(test_t), 4,
&dummy_pool, pool_alloc, pool_dealloc);
assert(pa != NULL);
t = (test_t *)mln_array_push(pa);
assert(t != NULL);
mln_array_free(pa);
printf("ALL PASSED\n");
return 0;
}