mem.h(3)

📦
version 2.2.0 · 2 versions
, in fedora 44

🌸 NAME 🌸

okay so welcome to the mem.h(3) page bestie 💖 — it's a Library Functions Manual moment, and it's all about memory management (the original calls it «Управление памятью», iykyk). Basically: everything you need to boss your raw octet strings around. no cap. ✨


🦋 SYNOPSIS 🦋

#include 'bee2/defs.h'
#include 'bee2/core/safe.h'

✨ Классы (Classes) ✨

  • union mem_align_t — the fundamental block (фундаментальный блок) 👑

✨ Макросы (Macros) ✨

  • #define memCopyIf(dest, src, count)
  • #define memSetZero(buf, count)
  • #define memIsNullOrValid(buf, count) — null pointer, or a valid memory buffer? (нулевой указатель или корректный буфер памяти?) 🧐

✨ Функции (Functions) ✨

  • void memCopy(void *dest, const void *src, size_t count) — copy a memory buffer
  • void memMove(void *dest, const void *src, size_t count) — move a memory buffer
  • void memSet(void *buf, octet c, size_t count) — fill a memory buffer
  • void memNeg(void *buf, size_t count) — invert a memory buffer
  • bool_t memIsAligned(const void *p, size_t alignment) — is the pointer aligned to a block boundary?
  • void *memAlloc(size_t count) — allocate a memory block
  • void *memRealloc(void *buf, size_t count) — resize a memory block
  • void memFree(void *buf) — free a memory block
  • bool_t memIsValid(const void *buf, size_t count) — is this a valid memory buffer?
  • bool_t memEq(const void *buf1, const void *buf2, size_t count) — match check
  • int memCmp(const void *buf1, const void *buf2, size_t count) — comparison
  • int memCmpRev(const void *buf1, const void *buf2, size_t count) — reverse comparison
  • void memWipe(void *buf, size_t count) — wipe a memory buffer
  • bool_t memIsZero(const void *buf, size_t count) — is this a zero memory buffer?
  • size_t memNonZeroSize(const void *buf, size_t count) — size of the significant part of the buffer
  • bool_t memIsRep(const void *buf, size_t count, octet o) — octet repeat?
  • void memJoin(void *dest, const void *src1, size_t count1, const void *src2, size_t count2) — join two buffers
  • bool_t memIsDisjoint(const void *buf1, const void *buf2, size_t count) — do same-size buffers not overlap?
  • bool_t memIsSameOrDisjoint(const void *buf1, const void *buf2, size_t count) — do the buffers match, or not overlap?
  • bool_t memIsDisjoint2(const void *buf1, size_t count1, const void *buf2, size_t count2) — do two buffers not overlap?
  • bool_t memIsDisjoint3(const void *buf1, size_t count1, const void *buf2, size_t count2, const void *buf3, size_t count3) — do three buffers not overlap?
  • bool_t memIsDisjoint4(const void *buf1, size_t count1, const void *buf2, size_t count2, const void *buf3, size_t count3, const void *buf4, size_t count4) — do four buffers not overlap?
  • void memXor(void *dest, const void *src1, const void *src2, size_t count) — addition of memory octets modulo 2
  • void memXor2(void *dest, const void *src, size_t count) — adding memory octets modulo 2
  • void memSwap(void *buf1, void *buf2, size_t count) — swap memory octets
  • void memRev(void *buf, size_t count) — reverse octets
  • void memSlice(const void *buf, size_t c1, ...) — mark up a memory buffer
  • size_t memSliceSize(size_t c1, ...) — size of the buffer being marked up
  • void *memSliceNext(void *ptr, size_t count) — next fragment of marked-up memory
  • const void *memSliceNext2(const void *ptr, size_t count) — next fragment of marked-up constant memory

💜 Подробное описание (DESCRIPTION) 💜

so like. this header implements or overrides a whole bunch of manipulations over memory buffers, and every single one of those buffers is interpreted as a string of octets. periodt. 💅

The xxTo() and xxFrom() functions do the converting thing — they transform between memory buffers and other data structures. And there are two flavors of them: simple and complex.

  • In the simple ones, the amount of memory needed to hold the converted data is known right away. You hand them a valid pointer to the destination buffer, and simple functions don't return anything at all. not a single value. iconic.
  • In the complex ones, the output size is computed from the input and handed back to you as the return value. You're allowed to pass a null pointer as the destination buffer, get the required buffer size back, reserve yourself a buffer, and then call the function one more time. main character energy fr fr ✨

A memory buffer can represent an array of u16, u32, u64, or word words. 🌈

The LITTLE_ENDIAN conventions are the standard ones (see defs.h). So on platforms with BIG_ENDIAN conventions, when a word is loaded from memory — and, the other way around, when a word is stored into memory — the octets of the word get reversed. 🦋

In memAlloc(), memRealloc(), memSlice() and memSlice2(), pointers are aligned to the boundary of the fundamental block. The fundamental block encapsulates all scalar types of Bee2. At an address aligned to a block boundary you can place any scalar type, and therefore literally any object. slay. 👑

Предусловие (Precondition) 🎀 — unless stated otherwise, the functions are handed valid memory buffers. every time. no exceptions bestie.

🎀 Макросы (MACROS) 🎀

#define memCopyIf( dest, src, count)

Macro definition:

((dest) && (src) ? memCopy(dest, src, count) : 0)

Copies [count]src into [count]dest — but only if the pointers src and dest are non-null. 💖

#define memSetZero( buf, count)

Macro definition:

memSet(buf, 0, count)

The [count]buf buffer gets zeroed out. poof. ✨


🔥 Функции (FUNCTIONS) 🔥

void * memAlloc (size_t count)

Allocates a block of dynamic memory made of count octets. 💅

Возвращает (Returns) — a pointer to the memory block, or 0 if there isn't enough memory. 😭

Постусловие (Postcondition) — the returned pointer p is aligned to the boundary of the fundamental block: memIsAligned(p, sizeof(mem_block_t)) == TRUE.

Прим. (Note) — calling memAlloc(0) is allowed. The result of the call may be a null pointer. That null pointer can still be passed into memRealloc() and memFree(). 🫶

Аргументы (Arguments) — count — size of the block

int FAST memCmp (const void * buf1, const void * buf2, size_t count)

Buffers [count]buf1 and [count]buf2 are compared lexicographically. 📚

Возвращает (Returns) — < 0 if [count]buf1 < [count]buf2, 0 if [count]buf1 == [count]buf2,

0 if [count]buf1 > [count]buf2.

Прим. (Note) — octets of the buffers are compared sequentially, from first to last. The first mismatch is what sets the relation between the buffers. no cap.

Регулярность (Regularity) — a faster irregular edition exists. 🔥

Прим. (Note) — the comparison logic of the standard memcmp() function is repeated.

Аргументы (Arguments)

  • buf1 — first buffer
  • buf2 — second buffer
  • count — size of the buffers

Перекрестные ссылки (Cross references) — memCmp().

Используется в (Used in) — memCmp().

int FAST memCmpRev (const void * buf1, const void * buf2, size_t count)

Buffers [count]buf1 and [count]buf2 are compared in reverse-lexicographic order. 🔄

Возвращает (Returns) — < 0 if [count]buf1 < [count]buf2, 0 if [count]buf1 == [count]buf2,

0 if [count]buf1 > [count]buf2.

Прим. (Note) — octets of the buffers are compared sequentially, from last to first. The first mismatch is what sets the relation between the buffers.

Регулярность (Regularity) — a faster irregular edition exists. 🔥

Аргументы (Arguments)

  • buf1 — first buffer
  • buf2 — second buffer
  • count — size of the buffers

Перекрестные ссылки (Cross references) — memCmpRev().

Используется в (Used in) — memCmpRev().

void memCopy (void * dest, const void * src, size_t count)

The octets of the [count]src buffer get rewritten into the [count]dest buffer. ✨

Предусловие (Precondition) — the buffers src and dest do not overlap. bestie please. do not. 🙈

bool_t FAST memEq (const void * buf1, const void * buf2, size_t count)

Checks that the contents of the [count]buf1 and [count]buf2 buffers match up. 🫶

Возвращает (Returns) — the match flag.

Регулярность (Regularity) — a faster irregular edition exists. 🔥

Аргументы (Arguments)

  • buf1 — first buffer
  • buf2 — second buffer
  • count — size of the buffers

Перекрестные ссылки (Cross references) — memEq().

Используется в (Used in) — memEq().

void memFree (void * buf)

Frees the dynamic memory block buf. bye bestie 💀

Предусловие (Precondition) — buf must have been allocated with memAlloc() or memRealloc().

Аргументы (Arguments) — buf — buffer

memIsAligned

bool_t memIsAligned (const void * p, size_t alignment)

Окей, бести, эта функция проверяет, что указатель p выровнен на границу блока из align октетов. Выравнивание — это святое 💅

Возвращает: проверяемый признак. То есть TRUE или FALSE, ты поняла ✨

Аргументы:

  • p — указатель
  • alignment — длина блока

memIsDisjoint

bool_t memIsDisjoint (const void * buf1, const void * buf2, size_t count)

Проверяет, что буфер [count]buf1 не пересекается с буфером [count]buf2. Типа они не наезжают друг на друга 🚫

Возвращает: проверяемый признак.

Предусловие: буферы buf1 и buf2 корректны. Не забудь, а то будет грусть 😭

Аргументы:

  • buf1 — первый буфер
  • buf2 — второй буфер
  • count — размер буферов

memIsDisjoint2

bool_t memIsDisjoint2 (const void * buf1, size_t count1, const void * buf2,
       size_t count2)

Проверяет, что буфер [count1]buf1 не пересекается с буфером [count2]buf2. Двойная проверка, но с разными размерами 💫

Возвращает: проверяемый признак.

Предусловие: буферы buf1 и buf2 корректны.

Аргументы:

  • buf1 — первый буфер
  • count1 — размер buf1
  • buf2 — второй буфер
  • count2 — размер buf2

memIsDisjoint3

bool_t memIsDisjoint3 (const void * buf1, size_t count1, const void * buf2,
       size_t count2, const void * buf3, size_t count3)

Проверяет, что буферы [count1]buf1, [count2]buf2 и [count3]buf3 попарно не пересекаются. Тройная угроза, но без пересечений 🔥

Возвращает: проверяемый признак.

Предусловие: буферы buf1, buf2 и buf3 корректны.

Аргументы:

  • buf1 — первый буфер
  • count1 — размер buf1
  • buf2 — второй буфер
  • count2 — размер buf2
  • buf3 — третий буфер
  • count3 — размер buf3

memIsDisjoint4

bool_t memIsDisjoint4 (const void * buf1, size_t count1, const void * buf2,
       size_t count2, const void * buf3, size_t count3, const void * buf4,
       size_t count4)

Проверяет, что буферы [count1]buf1, [count2]buf2, [count3]buf3 и [count4]buf4 попарно не пересекаются. Четыре буфера, ноль пересечений — это магия 🌈

Возвращает: проверяемый признак.

Предусловие: буферы buf1, buf2, buf3 и buf4 корректны.

Аргументы:

  • buf1 — первый буфер
  • count1 — размер buf1
  • buf2 — второй буфер
  • count2 — размер buf2
  • buf3 — третий буфер
  • count3 — размер buf3
  • buf4 — четвертый буфер
  • count4 — размер buf4

memIsRep

bool_t FAST memIsRep (const void * buf, size_t count, octet o)

Проверяет, что [count]buf заполнен октетом o. Типа все байтики одинаковые 💅

Прим.: Считается, что в пустом буфере (count == 0) повторяется значение 0. Пустой буфер — это тоже повтор, но нуля 😌

Возвращает: признак успеха.

Регулярность: имеется ускоренная нерегулярная редакция. Скорость зависит от данных, так что не жди стабильности ⚡

Аргументы:

  • buf — буфер
  • count — размер буфера
  • o — значение

Перекрестные ссылки: memIsRep().

Используется в: memIsRep().


memIsSameOrDisjoint

bool_t memIsSameOrDisjoint (const void * buf1, const void * buf2, size_t
       count)

Проверяет, что буфер [count]buf1 совпадает или не пересекается с буфером [count]buf2. Либо они одинаковые, либо вообще не пересекаются 🤝

Возвращает: проверяемый признак.

Предусловие: буферы buf1 и buf2 корректны.

Аргументы:

  • buf1 — первый буфер
  • buf2 — второй буфер
  • count — размер буферов

memIsValid

bool_t memIsValid (const void * buf, size_t count)

Проверяет, что [count]buf является корректным буфером. Валидность — это база ✅

Возвращает: проверяемый признак.

Прим.: Нулевой указатель buf является корректным, если count == 0. Ноль октетов — ноль проблем 🫶

Аргументы:

  • buf — буфер
  • count — размер буфера

memIsZero

bool_t FAST memIsZero (const void * buf, size_t count)

Проверяет, что буфер [count]buf является нулевым. Все байтики — нолики 0️⃣

Возвращает: проверяемый признак.

Регулярность: имеется ускоренная нерегулярная редакция.

Аргументы:

  • buf — буфер
  • count — размер буфера

Перекрестные ссылки: memIsZero().

Используется в: memIsZero().


memJoin

void memJoin (void * dest, const void * src1, size_t count1, const void *
       src2, size_t count2)

В dest записывается блок [count1]src1 || [count2]src2. Склеиваем два буфера в один 🧬

Предусловие: По адресам src1, src2, dest зарезервировано count1, count2 и count1 + count2 октетов памяти соответственно. Не забудь про место, иначе будет беда 💀

Прим.: Буферы src1, src2 и dest могут пересекаться. Они могут пересекаться, так что не удивляйся 😮

Аргументы:

  • dest — назначение
  • src1 — первый источник
  • count1 — число октетов src1
  • src2 — второй источник
  • count2 — число октетов src2

memMove

void memMove (void * dest, const void * src, size_t count)

Октеты буфера [count]src перемещаются в буфер [count]dest. Двигаем байтики 🚚

Предусловие: Буферы src и dest могут пересекаться. Да, даже если пересекаются, всё будет ок 👌


memNeg

void memNeg (void * buf, size_t count)

Все биты буфера [count]buf инвертируются. Флипаем битики 🔄


memNonZeroSize

size_t memNonZeroSize (const void * buf, size_t count)

Определяется размер значащей части буфера [count]buf. Незначащими считаются последние нулевые октеты буфера вплоть до первого ненулевого. Ищем, где заканчивается смысл 🔍

Возвращает: размер значащей части в октетах.

Регулярность: функция нерегулярна: время выполнения зависит от заполнения buf. Опять скорость зависит от данных ⏳

Аргументы:

  • buf — буфер
  • count — размер буфера

memRealloc

void * memRealloc (void * buf, size_t count)

Размер блока динамической памяти buf устанавливается равным count. При необходимости блок перемещается в памяти. Содержимое блока максимально сохраняется. Меняем размер, сохраняем что можем 🧠

Возвращает: Указатель на блок памяти с новым размером или 0, если count == 0 или памяти не хватает. Если ноль — значит всё, приехали 🚫

Постусловие: Возвращаемый указатель p выровнен на границу фундаментального блока: memIsAligned(p, sizeof(mem_block_t)) == TRUE. Выравнивание — наше всё 💅

Прим.: memRealloc(buf, 0) равносильно memFree(buf). Обнулил размер — освободил память 🗑️

Аргументы:

  • buf — блок памяти
  • count — размер блока

memRev

void memRev (void * buf, size_t count)

Октеты буфера [count]buf записываются в обратном порядке. Разворачиваем всё назад 🔄

Аргументы:

  • buf — буфер
  • count — размер буфера

memSet

void memSet (void * buf, octet c, size_t count)

Буфер [count]buf заполняется октетом c. Заливаем байтики одним значением 🎨


memSlice

void memSlice (const void * buf, size_t c1,  ...)

Буфер buf разбивается на фрагменты [c1]p1, ..., [cn]pn. Фрагменты описываются параметрами c1 и .... Описание имеет вид: с1, c2, ..., cn, SIZE_MAX, pp1, pp2, ..., ppn, где сi — длина фрагмента в октетах (size_t), SIZE_MAX — маркер окончания списка длин, ppi — указатель на pi (const void**). При установке в сi флага SIZE_HI указатель pi повторяет предыдущий, если таковой имеется. Это позволяет использовать один и тот же участок памяти в разные моменты времени для размещения разных объектов. Типа нарезаем буфер на кусочки и раздаём их 🍰

Предусловие: Указатель buf выровнен на границу фундаментального блока: memIsAligned(buf, sizeof(mem_block_t)) == TRUE. Указатели ppi корректны. Выравнивание и корректность — обязательны ✅

Постусловие: Указатели pi выровнены на границу фундаментального блока: memIsAligned(pi, sizeof(mem_block_t)) == TRUE. И на выходе тоже выравнивание 💅

Аргументы:

  • buf — буфер
  • c1 — начало описания фрагментов памяти
  • ... — окончание описания

memSliceNext

void * memSliceNext (void * ptr, size_t count)

Определяется указатель на фрагмент памяти, следующий за [count]ptr. Ищем следующий кусочек ➡️

Ожидается: Память размечена по правилам memSlice(). Разметка должна быть как в memSlice() 📏

Возвращает: Указатель на следующий фрагмент.

Аргументы:

  • ptr — указатель на начало фрагмента
  • count — длина фрагмента

memSliceNext2

const void * memSliceNext2 (const void * ptr, size_t count)

Определяется указатель на фрагмент постоянной памяти, следующий за [count]ptr. То же самое, но для константной памяти 🧊

Ожидается: Память размечена по правилам memSlice(). Правила те же 📏

Возвращает: Указатель на следующий фрагмент.

Аргументы:

  • ptr — указатель на начало фрагмента
  • count — длина фрагмента

memSliceSize

size_t memSliceSize (size_t c1,  ...)

Определяется объем памяти для размещения фрагментов памяти длин с1, с2, ..., cn, заданных параметрами c1 и .... Описание имеет вид: c1, c2, ..., cn, SIZE_MAX. Действуют соглашения memSlice(). Считаем, сколько места надо 📐

Возвращает: Суммарная длина фрагментов с учетом выравнивания и возможных пересечений фрагментов. С учётом выравнивания и пересечений 💅

🚨 Предупреждения 🚨

Суммарная длина фрагментов не обязательно кратна длине фундаментального блока, и это окей, не паникуй 💅. А вот если тебе прям кровь из носу нужна эта кратность — передавай в качестве cn величину SIZE_0. Вот и весь секрет, iykyk ✨

🧩 Аргументы 🧩

  • c1 — начало описания длин фрагментов памяти
  • ... — окончание описания

void memSwap (void * buf1, void * buf2, size_t count)

Октеты буферов [count]buf1 и [count]buf2 меняются местами 🔄 — буквально своп, как когда вы с бести обменялись аутфитами и обе ate 💖.

⚠️ Предусловие ⚠️

Буферы buf1 и buf2 не пересекаются. Прям вообще ни капельки, не надо их друг на друга накладывать, это не тот вайб 🙈

🧩 Аргументы 🧩

  • buf1 — первый буфер
  • buf2 — второй буфер
  • count — число октетов

void memWipe (void * buf, size_t count)

Буфер [count]buf очищается — в него записываются произвольные октеты 🧹✨. Типа стёрли и забыли, bye bestie.

📌 Прим. 📌

Запись выполняется всегда, даже если buf в дальнейшем не используется и включена оптимизация компиляции. То есть компилятор не вырежет этот вайп, он реально случится — no cap 👑

🧩 Аргументы 🧩

  • buf — буфер
  • count — размер буфера

void memXor (void * dest, const void * src1, const void * src2, size_t count)

В буфер [count]dest записывается поразрядно по модулю 2 сумма октетов октетов буферов [count]src1 и [count]src2. И да, там реально два раза «октетов» — я не редактирую, я переписываю 😭 верность оригиналу — это бренд.

⚠️ Предусловие ⚠️

Буфер dest либо не пересекается, либо совпадает с каждым из буферов src1, src2. Третьего не дано, не выдумывай 💅

🧩 Аргументы 🧩

  • dest — сумма
  • src1 — первое слагаемое
  • src2 — второе слагаемое
  • count — число октетов

void memXor2 (void * dest, const void * src, size_t count)

К октетам буфера [count]dest добавляются октеты буфера [count]src. Сложение выполняется поразрядно по модулю 2. Это как memXor, только у тебя уже есть одно слагаемое на месте, main character energy ✨

⚠️ Предусловие ⚠️

Буфер dest либо не пересекается, либо совпадает с буфером src. Всё, других вариантов нет 🫶

🧩 Аргументы 🧩

  • dest — второе слагаемое / сумма
  • src — первое слагаемое
  • count — число октетов

✨ Автор ✨

Автоматически создано Doxygen для Библиотека Bee2 из исходного текста. Спасибо, Doxygen, ты сделал всю работу, а я просто навела красоту 🎀


И всё, страничка закончилась, обнимаю 🦋 Эта красота живёт в Библиотеке Bee2, собрана Вс 25 Янв 2026 00:00:00, и зовётся она нежно — mem.h(3). Иди пиши код, бести, ты справишься 💜🌸

📦 where this page comes from