#ifndef VLIBC_STDLIB_H #define VLIBC_STDLIB_H /* * vlibc — . * * This header is the shared home for the stdlib declarations; it currently * holds only the memory-management family (todo 7). Later todos extend it * in place: todo 11 adds the numeric conversions (atoi/strtol/strtod/...), * todo 12 the pseudo-random and search/divide functions * (rand/srand/qsort/bsearch/abs/div/...), and todo 13 the environment and * multibyte helpers (getenv/setenv/mblen/mbtowc/...). * * Memory management functions, gated by the active compatibility profile * (see include/vlibc/features.h). Levels are cumulative: * * Level 1 (onlyposix): ISO C core + POSIX base — malloc, free, calloc, * realloc, aligned_alloc, posix_memalign. * Level 2 (muslmimic): malloc_usable_size (BSD/musl). * * This header includes itself, so the gates below always * see the configured VLIBC_LEVEL even when the caller included no vlibc * header first, and for size_t. */ #include #include #ifdef __cplusplus extern "C" { #endif /* Level 1: memory management (always present). */ /* * Allocate size bytes, 16-byte aligned. The memory is uninitialized. * malloc(0) returns a unique minimum-size block (never NULL on success). * NULL + errno ENOMEM on failure. * malloc: the result does not alias any other pointer and has size bytes. */ __attribute__((malloc, alloc_size(1))) void * malloc(size_t size); /* * Release the block at ptr, which must be NULL or a value returned by an * earlier allocation in this family. free(NULL) is a no-op. */ void free(void *ptr); /* * Allocate an array of nmemb elements of size bytes each, all bits zero. * The product is overflow-checked: on overflow NULL + errno ENOMEM. * calloc with a zero product returns a unique zeroed minimum-size block. * malloc: the result does not alias any other pointer and has nmemb*size * bytes. */ __attribute__((malloc, alloc_size(1, 2))) void * calloc(size_t nmemb, size_t size); /* * Resize the block at ptr to size bytes, preserving the first min(old, * size) bytes. realloc(NULL, size) behaves as malloc(size); realloc(ptr, 0) * frees ptr and returns NULL. The old block is freed on success and left * untouched on failure (NULL + errno ENOMEM). * alloc_size(2): the result has size bytes. */ __attribute__((alloc_size(2))) void * realloc(void *ptr, size_t size); /* * Allocate size bytes aligned to alignment. alignment must be a power of * two that is a multiple of sizeof(void *), and size must be a multiple of * alignment; a violation fails with NULL + errno EINVAL (a non-power-of-two * alignment is undefined behavior in C23, so only well-formed arguments * reach the allocator). size 0 returns NULL. The result is released with * free. * malloc + alloc_align(1): the result does not alias any other pointer and * is aligned to alignment. */ __attribute__((malloc, alloc_size(2), alloc_align(1))) void * aligned_alloc(size_t alignment, size_t size); /* * Allocate size bytes at address alignment and store the result in * *memptr. alignment must be a power of two and a multiple of * sizeof(void *). Returns 0 on success, EINVAL for a bad alignment, ENOMEM * on allocation failure. Never sets errno itself, and never modifies * *memptr on failure. size 0 returns a unique minimum-size block. */ __attribute__((access(write_only, 1))) int posix_memalign(void **memptr, size_t alignment, size_t size); #if VLIBC_LEVEL_GE(2) /* Level 2 (muslmimic): BSD/musl extensions. */ /* * Return the number of bytes actually available in the block at ptr, * including any internal padding; at least as large as the requested size. * ptr may be any block returned by the allocator family; NULL returns 0. * pure: reads memory, no side effects. */ __attribute__((pure)) size_t malloc_usable_size(void *ptr); #endif /* VLIBC_LEVEL_GE(2) */ #ifdef __cplusplus } #endif #endif /* VLIBC_STDLIB_H */