Модуль stdlib.h предоставляет стандартные функции языка C (функции прошивки) для работы с динамической памятью, преобразованием строк в числа, генерацией псевдослучайных чисел, математическими операциями, управлением завершением программы и поиском/сортировкой данных.

Для работы с модулем stdlib.h реализованы следующие функции:

  // Управление динамической памятью
void *malloc(size_t size);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
void free(void *ptr);

// Преобразование строк в числа
int atoi(const char *nptr);
long atol(const char *nptr);
long long atoll(const char *nptr);
double atof(const char *nptr);
long strtol(const char *nptr, char **endptr, int base);
long long strtoll(const char *nptr, char **endptr, int base);
unsigned long strtoul(const char *nptr, char **endptr, int base);
unsigned long long strtoull(const char *nptr, char **endptr, int base);
float strtof(const char *nptr, char **endptr);
double strtod(const char *nptr, char **endptr);
long double strtold(const char *nptr, char **endptr);

// Генерация псевдослучайных чисел
int rand(void);
void srand(unsigned int seed);

// Математические операции
int abs(int x);
long labs(long x);
long long llabs(long long x);
div_t div(int numer, int denom);
ldiv_t ldiv(long numer, long denom);
lldiv_t lldiv(long long numer, long long denom);

// Управление завершением программы
void abort(void);
void exit(int status);
int atexit(void (*func)(void));

// Поиск и сортировка
void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
  

Особенности контроллера

Функции объявлены в заголовках компилятора сценариев, а выполняются в прошивке. Полной среды настольной ОС нет. Динамическая куча использует прежнюю область размером 8200 байт; служебные заголовки, выравнивание и фрагментация уменьшают доступный объём. Указатели malloc/calloc/realloc выровнены на 8 байт. Память между отдельными сценариями не сохраняет контракт выделения; старый указатель повторно использовать нельзя.

Выход за границы выделения, неверный указатель и повторный free не являются допустимым использованием API, даже если allocator отклоняет некоторые такие вызовы. У malloc нет гарантии обнуления. Правила начального обнуления глобальных и статических переменных описаны в особенностях C.

malloc

void *malloc(size_t size) выделяет size байт. При нуле или недопустимом размере, включая переполнение округления и размер больше кучи, возвращает NULL. При нехватке непрерывного свободного блока также возвращает NULL. Память не обнуляется.

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

int main(void) {
    uint8_t *buffer = malloc(64);
    if (buffer == NULL) {return 1;}
    memset(buffer, 0, 64);
    printf("Buffer: %u bytes\n", 64U);
    free(buffer);
    return 0;
}
  

calloc

void *calloc(size_t nmemb, size_t size) выделяет nmemb*size байт и обнуляет их. Проверяет переполнение произведения и размер до выделения. Возвращает NULL при нулевом общем размере, слишком большом запросе или нехватке памяти.

realloc

void *realloc(void *ptr, size_t size) меняет размер выделения. Данные сохраняются до меньшего из старого и нового размеров; добавленные байты не инициализированы. При уменьшении свободный хвост объединяется с соседним свободным блоком.

NULL в ptr означает malloc(size); size=0 освобождает ptr и возвращает NULL. При отказе с ненулевым size старое выделение сохраняется: сначала проверяйте временный указатель.

  #include <dev.h>
#include <stdlib.h>

int main(void) {
    uint8_t *buffer = malloc(32);
    if (buffer == NULL) {return 1;}
    uint8_t *larger = realloc(buffer, 64);
    if (larger == NULL) {free(buffer); return 1;}
    buffer = larger;
    free(buffer);
    return 0;
}
  

free

void free(void *ptr) освобождает выделение из кучи C-сценария и объединяет соседние свободные блоки. free(NULL) ничего не делает. Передавайте только адрес начала действующего выделения; после освобождения обращение через указатель недопустимо.

atoi

Функция int atoi(const char *nptr) преобразует строку nptr в целое число типа int.

Параметры:

  • nptr — указатель на строку.

Возвращаемые значения:

  • Целое число или 0, если преобразование невозможно.

Примечание: Не сообщает об ошибках. Рекомендуется использовать strtol для большей надёжности.

Пример использования:

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

int main(void) {
    const char *str = "123";
    int num = atoi(str);
    printf("Число: %d\n", num); // Ожидается: 123
    return 0;
}
  

atol

Функция long atol(const char *nptr) преобразует строку nptr в целое число типа long.

Параметры:

  • nptr — указатель на строку.

Возвращаемые значения:

  • Целое число или 0, если преобразование невозможно.

Пример использования:

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

int main(void) {
    const char *str = "123456";
    long num = atol(str);
    printf("Число: %ld\n", num); // Ожидается: 123456
    return 0;
}
  

atoll

Функция long long atoll(const char *nptr) преобразует строку nptr в целое число типа long long.

Параметры:

  • nptr — указатель на строку.

Возвращаемые значения:

  • Целое число или 0, если преобразование невозможно.

Пример использования:

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

int main(void) {
    const char *str = "123456789";
    long long num = atoll(str);
    printf("Число: %lld\n", num); // Ожидается: 123456789
    return 0;
}
  

atof

Функция double atof(const char *nptr) преобразует строку nptr в число с плавающей точкой типа double.

Параметры:

  • nptr — указатель на строку.

Возвращаемые значения:

  • Число с плавающей точкой или 0.0, если преобразование невозможно.

Пример использования:

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

int main(void) {
    const char *str = "3.14159";
    double num = atof(str);
    printf("Число: %.5f\n", num); // Ожидается: 3.14159
    return 0;
}
  

strtol

Функция long strtol(const char *nptr, char **endptr, int base) преобразует строку nptr в число типа long с указанием системы счисления base.

Параметры:

  • nptr — указатель на строку.
  • endptr — указатель на указатель, куда записывается адрес первого непроанализированного символа (или NULL).
  • base — система счисления (2–36 или 0 для автоопределения).

Возвращаемые значения:

  • Преобразованное число. Если цифр нет, возвращается 0 и endptr совпадает с началом строки. При переполнении возвращается граница типа, а не обязательно 0. Интерфейс errno сценариям не предоставлен: проверяйте endptr и прикладной диапазон.

Пример использования:

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

int main(void) {
    const char *str = "123abc";
    char *endptr;
    long num = strtol(str, &endptr, 10);
    printf("Число: %ld, остаток: %s\n", num, endptr); // Ожидается: Число: 123, остаток: abc
    return 0;
}
  

strtoll

Функция long long strtoll(const char *nptr, char **endptr, int base) преобразует строку nptr в число типа long long.

Параметры:

  • Аналогично strtol.

Возвращаемые значения:

  • Аналогично strtol.

Пример использования:

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

int main(void) {
    const char *str = "123456789abc";
    char *endptr;
    long long num = strtoll(str, &endptr, 10);
    printf("Число: %lld, остаток: %s\n", num, endptr); // Ожидается: Число: 123456789, остаток: abc
    return 0;
}
  

strtoul

Функция unsigned long strtoul(const char *nptr, char **endptr, int base) преобразует строку nptr в число типа unsigned long.

Параметры:

  • Аналогично strtol.

Возвращаемые значения:

  • Аналогично strtol.

Пример использования:

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

int main(void) {
    const char *str = "0xFFabc";
    char *endptr;
    unsigned long num = strtoul(str, &endptr, 16);
    printf("Число: %lu, остаток: %s\n", num, endptr); // Ожидается: Число: 255, остаток: abc
    return 0;
}
  

strtoull

Функция unsigned long long strtoull(const char *nptr, char **endptr, int base) преобразует строку nptr в число типа unsigned long long.

Параметры:

  • Аналогично strtol.

Возвращаемые значения:

  • Аналогично strtol.

Пример использования:

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

int main(void) {
    const char *str = "0xFFFFabc";
    char *endptr;
    unsigned long long num = strtoull(str, &endptr, 16);
    printf("Число: %llu, остаток: %s\n", num, endptr); // Ожидается: Число: 65535, остаток: abc
    return 0;
}
  

strtof

Функция float strtof(const char *nptr, char **endptr) преобразует строку nptr в число типа float.

Параметры:

  • nptr — указатель на строку.
  • endptr — указатель на указатель, куда записывается адрес первого непроанализированного символа (или NULL).

Возвращаемые значения:

  • Преобразованное число; если преобразования нет, 0.0 и endptr указывает на начало строки. Переполнение может дать бесконечность, потеря значимости — ноль или субнормальное число. Не используйте один нулевой результат как единственный признак ошибки; API errno не предоставлен.

Пример использования:

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

int main(void) {
    const char *str = "3.14159abc";
    char *endptr;
    float num = strtof(str, &endptr);
    printf("Число: %.5f, остаток: %s\n", num, endptr); // Ожидается: Число: 3.14159, остаток: abc
    return 0;
}
  

strtod

Функция double strtod(const char *nptr, char **endptr) преобразует строку nptr в число типа double.

Параметры:

  • Аналогично strtof.

Возвращаемые значения:

  • Аналогично strtof.

Пример использования:

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

int main(void) {
    const char *str = "3.14159abc";
    char *endptr;
    double num = strtod(str, &endptr);
    printf("Число: %.5f, остаток: %s\n", num, endptr); // Ожидается: Число: 3.14159, остаток: abc
    return 0;
}
  

strtold

Функция long double strtold(const char *nptr, char **endptr) преобразует строку nptr в число типа long double.

Параметры:

  • Аналогично strtof.

Возвращаемые значения:

  • Аналогично strtof.

Пример использования:

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

int main(void) {
    const char *str = "3.1415926535abc";
    char *endptr;
    long double num = strtold(str, &endptr);
    printf("Число: %.10Lf, остаток: %s\n", num, endptr); // Ожидается: Число: 3.1415926535, остаток: abc
    return 0;
}
  

rand

int rand(void) вызывает программный генератор Yasmarang с верхней исключённой границей 0x7fffffff. Текущая реализация возвращает 0..2147483646, хотя макрос RAND_MAX в поставляемом заголовке равен 32767. Это несоответствие заголовка и реализации: не нормируйте результат делением на RAND_MAX. Для заданного диапазона используйте random(start, stop) с start < stop.

srand

void srand(unsigned int seed) меняет только компонент yasmarang_dat общего состояния генератора. Другие компоненты не сбрасываются. В этой реализации повторный srand с тем же seed не гарантирует воспроизведения всей последовательности rand. Не используйте этот механизм для криптографии.

Для abs/labs/llabs аргумент не должен быть минимальным отрицательным числом своего типа: его положительное значение не представимо. Для div/ldiv/lldiv запрещены нулевой делитель и деление минимального отрицательного числа на -1.

abs

Функция int abs(int x) возвращает абсолютное значение числа типа int.

Параметры:

  • x — входное число.

Возвращаемые значения:

  • Абсолютное значение x.

Пример использования:

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

int main(void) {
    int x = -42;
    int res = abs(x);
    printf("Абсолютное значение: %d\n", res); // Ожидается: 42
    return 0;
}
  

labs

Функция long labs(long x) возвращает абсолютное значение числа типа long.

Параметры:

  • x — входное число.

Возвращаемые значения:

  • Абсолютное значение x.

Пример использования:

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

int main(void) {
    long x = -123456L;
    long res = labs(x);
    printf("Абсолютное значение: %ld\n", res); // Ожидается: 123456
    return 0;
}
  

llabs

Функция long long llabs(long long x) возвращает абсолютное значение числа типа long long.

Параметры:

  • x — входное число.

Возвращаемые значения:

  • Абсолютное значение x.

Пример использования:

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

int main(void) {
    long long x = -123456789LL;
    long long res = llabs(x);
    printf("Абсолютное значение: %lld\n", res); // Ожидается: 123456789
    return 0;
}
  

div

Функция div_t div(int numer, int denom) выполняет деление numer на denom и возвращает частное и остаток.

Параметры:

  • numer — числитель.
  • denom — знаменатель.

Возвращаемые значения:

  • Структура div_t с полями quot (частное) и rem (остаток).

Пример использования:

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

int main(void) {
    div_t result = div(17, 5);
    printf("Частное: %d, Остаток: %d\n", result.quot, result.rem); // Ожидается: Частное: 3, Остаток: 2
    return 0;
}
  

ldiv

Функция ldiv_t ldiv(long numer, long denom) выполняет деление numer на denom для чисел типа long.

Параметры:

  • numer — числитель.
  • denom — знаменатель.

Возвращаемые значения:

  • Структура ldiv_t с полями quot и rem.

Пример использования:

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

int main(void) {
    ldiv_t result = ldiv(123456L, 100L);
    printf("Частное: %ld, Остаток: %ld\n", result.quot, result.rem); // Ожидается: Частное: 1234, Остаток: 56
    return 0;
}
  

lldiv

Функция lldiv_t lldiv(long long numer, long long denom) выполняет деление numer на denom для чисел типа long long.

Параметры:

  • numer — числитель.
  • denom — знаменатель.

Возвращаемые значения:

  • Структура lldiv_t с полями quot и rem.

Пример использования:

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

int main(void) {
    lldiv_t result = lldiv(123456789LL, 100LL);
    printf("Частное: %lld, Остаток: %lld\n", result.quot, result.rem); // Ожидается: Частное: 1234567, Остаток: 89
    return 0;
}
  

abort

void abort(void) немедленно завершает текущий C-сценарий с причиной «ошибка», пропуская atexit-обработчики. Функция не возвращается. Это штатное завершение задачи, а не перезагрузка контроллера и не генерация HardFault. Сообщение об abort сохраняется в /txt?log.

exit

void exit(int status) завершает текущий C-сценарий и вызывает atexit-обработчики в обратном порядке. Не возвращается. status=0 означает успех, ненулевой status — ошибку; ненулевой код записывается в /txt?log. Возврат значения из main имеет ту же семантику завершения. Файлового stdout и его сброса в этом API нет.

atexit

int atexit(void (*func)(void)) регистрирует до 32 обработчиков в существующей задаче сценария. Возвращает 0 при успехе, -1 для NULL, переполнения списка или вызова вне активного C-сценария. Одна функция может быть зарегистрирована несколько раз.

Обработчики вызываются при обычном return из main и exit, начиная с последнего. abort их пропускает. Внешняя принудительная остановка не гарантирует их вызова. В текущей реализации exit из обработчика продолжает завершение с оставшимися обработчиками; abort из обработчика прекращает их вызов. Зацикленный обработчик задерживает завершение.

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

static void finish(void) {
    puts("Finished");
}

int main(void) {
    if (atexit(finish) != 0) {return 1;}
    puts("Started");
    return 0;
}
  

bsearch

Функция void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) выполняет бинарный поиск в отсортированном массиве.

Параметры:

  • key — указатель на искомый элемент.
  • base — указатель на массив.
  • nmemb — количество элементов.
  • size — размер каждого элемента.
  • compar — функция сравнения, возвращающая отрицательное, нуль или положительное значение.

Возвращаемые значения:

  • Указатель на найденный элемент или NULL, если элемент не найден.

Пример использования:

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

int compare(const void *a, const void *b) {
    return (*(int *)a - *(int *)b);
}

int main(void) {
    int arr[] = {1, 3, 5, 7, 9};
    int key = 5;
    int *result = bsearch(&key, arr, 5, sizeof(int), compare);
    if (result) {
        printf("Найден: %d\n", *result); // Ожидается: Найден: 5
    } else {
        printf("Не найден\n");
    }
    return 0;
}
  

qsort

Функция void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) сортирует массив методом быстрой сортировки.

Параметры:

  • base — указатель на массив.
  • nmemb — количество элементов.
  • size — размер каждого элемента.
  • compar — функция сравнения, возвращающая отрицательное, нуль или положительное значение.

Возвращаемые значения:

  • Нет.

Пример использования:

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

int compare(const void *a, const void *b) {
    return (*(int *)a - *(int *)b);
}

int main(void) {
    int arr[] = {5, 2, 8, 1, 9};
    qsort(arr, 5, sizeof(int), compare);
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]); // Ожидается: 1 2 5 8 9
    }
    return 0;
}