Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.80/15: Рейтинг темы: голосов - 15, средняя оценка - 4.80
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141

Своя реализация malloc, calloc, realloc

10.02.2024, 13:02. Показов 4463. Ответов 44

Студворк — интернет-сервис помощи студентам
Доброго времени суток. Данные функции не работают подскажите в чем может быть дело. UB необработанные исключения и прочее в зависимости от фазы луны.
Походу я где-то туплю. Заранее благодарен за помощь.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
static constexpr void * xmalloc(size_type nmemb, size_type size)
{    
        size_type new_size = nmemb * size;  
        if ((new_size == 0 ) || ((SIZE_MAX / nmemb) < size) || !(_HEAP_MAXREQ > new_size)) [[unlikely]] {return nullptr; }      
        return _malloca(new_size);
}
static constexpr void * xcalloc(size_type nmemb, size_type size)
{    
        void * newptr = xmalloc(nmemb, size);
        if(newptr)[[likely]]{
            size_type new_size = nmemb * size;
            memset(newptr, 0 , new_size);
            return newptr;
        }else return nullptr;
        
}
static constexpr void * xrealloc(void * ptr, size_type nmemb, size_type size)
{assert(ptr);
        void * newptr = xmalloc(nmemb, size);
        if(newptr)[[likely]]{
            if (newptr != ptr) {
                size_type new_size = nmemb * size;
                memcpy(newptr, ptr, new_size);
                return newptr;
            }return ptr;
        }else return nullptr;
}
 
***
где-то в конце _freea(buf)
так выглядит реализация в библиотеке malloc.h как видно из кода если запрашиваемый размер больше _ALLOCA_S_THRESHOLD выделение должно происходить в куче.
C++
1
2
3
4
5
6
7
8
    #undef _malloca
    #define _malloca(size)                                                                 \
        __pragma(warning(suppress: 6255 6386))                                             \
        (_MallocaComputeSize(size) != 0                                                    \
            ? (((_MallocaComputeSize(size) <= _ALLOCA_S_THRESHOLD)                         \
                ? _MarkAllocaS(_alloca(_MallocaComputeSize(size)), _ALLOCA_S_STACK_MARKER) \
                : _MarkAllocaS(malloc(_MallocaComputeSize(size)), _ALLOCA_S_HEAP_MARKER))) \
            : NULL)
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
10.02.2024, 13:02
Ответы с готовыми решениями:

Можно ли выделять память под объект класса с помощью функций calloc, malloc или realloc?
Интересует данный вопрос. Можно ли и имеет ли вобще смысл например выделять память под объект класса с помощью функций calloc, malloc или...

В чем преимущества new и delete и могут ли они действительно заменить функции calloc, malloc, free, realloc?
Язык программирования C поддерживает функции динамического управления пямятью: calloc, malloc, free, realloc - которые неподдерживают...

Использование calloc/realloc/free
//calloc.cpp //Использование calloc #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;iostream&gt; #include &lt;locale&gt; using...

44
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141
15.02.2024, 15:53  [ТС]
Студворк — интернет-сервис помощи студентам
сделал тест скорости, вот код теста:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <chrono>
//static auto start_time = std::chrono::steady_clock::now();
static auto start_time = std::chrono::high_resolution_clock::now();
 
inline void StartCounter()
{
 
     start_time = std::chrono::steady_clock::now();
     //start_time = std::chrono::high_resolution_clock::now();
}
inline double GetCounter()
{
 
    auto end_time = std::chrono::steady_clock::now();
    //auto end_time = std::chrono::high_resolution_clock::now();
    auto elapsed_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time);
    return elapsed_ns.count() ;
}
int main()
{
    wchar_t * arr = nullptr;
    double c = 0.0;
m:
for(size_t i = 0; i < 10000; i++)
{ 
    StartCounter();
    arr =   (wchar_t *)x_alloc.xmalloc(i+1, sizeof(wchar_t));
    x_alloc.xfree();
    c+=GetCounter();
 
}std::cout <<(c/10000.0) <<" "  << std::endl; c = 0.0;
 
for(size_t i = 0; i < 10000; i++)
{ 
    StartCounter();
    arr =   (wchar_t *)_aligned_malloc((i+1)*sizeof(wchar_t),alignment);
    _aligned_free(arr);
    c+=GetCounter();
 
}std::cout <<(c/10000.0) <<" "  << std::endl; c = 0.0;
 
    system("Pause");
    goto m;
из класса убрал атомик (так как пока многопоток не буду использовать), добавил смещение адресов 32 для avx.
вот так выглядит мой кастомный malloc:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
pointer xmalloc(size_type nmemb, size_type size = t_size<value_type>)noexcept
{       
    size_type new_size = test_size (nmemb , size);  if(xalloc.error == err_allocate) [[unlikely]] { return nullptr; }
    
    if(xalloc.error == err_s)
    {
        xalloc.alloc_capacity=size_mem_buf;
        xalloc.alloc_free=size_mem_buf;
    }
    if (new_size < xalloc.alloc_free)[[likely]]
    {   
        xalloc.alloc_free-=new_size;
        if (xalloc.freeptr == nullptr) [[unlikely]]
        {
            xalloc.freeptr=buffer.ptr();
        }       
            newptr = xalloc.freeptr;
            xalloc.freeptr+=new_size;
            xalloc.alloc_size=new_size;
            xalloc.array_f=true;
            xalloc.error=allocate_ok;
    }
    else {
        if ((newptr = reinterpret_cast<pointer> (_aligned_malloc(new_size, alignment))) != nullptr)[[likely]]{
            xalloc.array_f=false;
            xalloc.error=allocate_ok;
            
        }else {xalloc.error=err_allocate; return nullptr; }
    }
    return newptr;      
}
буду дальше разбираться
из теста видно что работа на массиве гараздо быстрее.
Миниатюры
Своя реализация malloc, calloc, realloc   Своя реализация malloc, calloc, realloc  
0
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141
15.02.2024, 16:11  [ТС]
Цитата Сообщение от SmallEvil Посмотреть сообщение
- Форматирование кода.
- явные использования constexp без понимания что это и для чего он нужен.
- Про атомарики вам уже сказали.
- мне нравится так. (тем более это тестовый класс)
- я знаю зачем он нужен
- атомики пока убрал
Цитата Сообщение от SmallEvil Посмотреть сообщение
Тогда мы имеем бесконечную рекурсию. Нет?
нет!
Цитата Сообщение от SmallEvil Посмотреть сообщение
Это вообще ужас из прошлых веков и стиля Object Pascal
ничего там страшного нет на вкус и цвет все фломастеры разные.
Цитата Сообщение от SmallEvil Посмотреть сообщение
вы создаете путанный код, потом в нем путаетесь
мен все понятно и нечего там путаного.

Добавлено через 9 минут
Цитата Сообщение от SmallEvil Посмотреть сообщение
сколько это "много", и какого именно "выделения"(размеры + частота) памяти идется
такие тесты делал ставил счетчики количества выделений памяти и скорость работы тестил(для того проекта где хочу использовать кастомный аллокатор). Так как использую там амортизацию памяти с увеличением на каждом шаге в два, обращений за выделением памяти не так много(зависит от начального размера блока ). но все же занимает какое-то время, что навело на мысль сократить это время еще. На данный момент экспериментирую выявляя целесообразность такого подхода.
0
274 / 206 / 30
Регистрация: 26.11.2022
Сообщений: 910
15.02.2024, 17:07
тестить скорость работы линейного аллокатора бесполезно - ибо это всего одна инструкция процессора.
(правда для условия многопоточки она атомарная) Этот аллокатор всегда самый быстрый.

тестить скорость malloc - это ещё и уметь надо. никого не интересует скорость выделения и последующего освобождения памяти. проблемы со скоростью начинаются когда вы часто и в случайном порядке выделяете и освобождаете куски памяти - тоесть выделили 100000 кусков разного размера, потом начинаете тест - сколько-то случайных освободили, сколько-то новых выделили и тд. в malloc время тратится на поиск ранее освобожденного участка памяти, который можно использовать, если программа запросила кусок памяти. и malloc должен найти из всех свободных кусков наиболее подходящий по размеру - чтобы минимизировать фрагментацию.

ТС - вы не понимаете принципы использования линейного аллокатора - когда его надо использовать.
Основных два:
1) Для данных которые существуют в течении всего сремени работы программы - тоесть вы попросили у ОС кусок адресного пространства, сделали там линейный аллогатор и выделяете память которую не собираетесь освобождать до выхода из программы. При этом по мере использования аллокатора ОС будет задействовать реальную память.
2) Для алгоритмов которым для работы нужно выделять много мелких кусков памяти. При этом вы можете либо у ОС либо в куче запросить достаточного объёма блок памяти, сделать в нём линейный аллокатор и дать этому алгоритму - он его использует, а после вы целиком освобождаете (или повторно используете) весь кусок памяти - не задумываясь об освобождении всех тех мелких кусочков, которые навыделял алгоритм.
0
1 / 1 / 0
Регистрация: 30.03.2017
Сообщений: 141
15.02.2024, 17:37  [ТС]
Цитата Сообщение от Aledveu Посмотреть сообщение
тестить скорость работы линейного аллокатора бесполезно - ибо это всего одна инструкция процессора.
(правда для условия многопоточки она атомарная) Этот аллокатор всегда самый быстрый.

тестить скорость malloc - это ещё и уметь надо. никого не интересует скорость выделения и последующего освобождения памяти. проблемы со скоростью начинаются когда вы часто и в случайном порядке выделяете и освобождаете куски памяти - тоесть выделили 100000 кусков разного размера, потом начинаете тест - сколько-то случайных освободили, сколько-то новых выделили и тд. в malloc время тратится на поиск ранее освобожденного участка памяти, который можно использовать, если программа запросила кусок памяти. и malloc должен найти из всех свободных кусков наиболее подходящий по размеру - чтобы минимизировать фрагментацию.

ТС - вы не понимаете принципы использования линейного аллокатора - когда его надо использовать.
Основных два:
1) Для данных которые существуют в течении всего сремени работы программы - тоесть вы попросили у ОС кусок адресного пространства, сделали там линейный аллогатор и выделяете память которую не собираетесь освобождать до выхода из программы. При этом по мере использования аллокатора ОС будет задействовать реальную память.
2) Для алгоритмов которым для работы нужно выделять много мелких кусков памяти. При этом вы можете либо у ОС либо в куче запросить достаточного объёма блок памяти, сделать в нём линейный аллокатор и дать этому алгоритму - он его использует, а после вы целиком освобождаете (или повторно используете) весь кусок памяти - не задумываясь об освобождении всех тех мелких кусочков, которые навыделял алгоритм.
я знаю что такое аллокатор и для чего он нужен. я знаю для чего он мне нужен. Я в курсе о задержках при поисках свободных кусков памяти и фрагминтации. Ну во-первых я экспериментирую с данными функциями, во вторых если эксперимент окажется удачным я знаю где использовать свою реализацию. И вообще я пришел с микроконтроллеров и си-ассемблера для них, поэтому не остановлюсь пока не добьюсь того чего мне надо или пойму, что это не достижимо или нецелесообразно. Лучше давать рекомендации по функционалу и логике работы, чем о код стайле и прочем не важном. С++ вообще сложный и перегруженный функционалом язык его никто не знает полностью, даже те кто тут пишут на форуме. Все просто опыт использования.

Добавлено через 52 секунды
Цитата Сообщение от Signum7 Посмотреть сообщение
тестить скорость работы линейного аллокатора бесполезно
как раз интересно сравнить! и если есть профит так почему не использовать
0
274 / 206 / 30
Регистрация: 26.11.2022
Сообщений: 910
15.02.2024, 20:13
Цитата Сообщение от Signum7 Посмотреть сообщение
С++ вообще сложный и перегруженный функционалом язык его никто не знает полностью
Я, например, не пишу на С++ ибо мне он нафиг не нужен, мне С хватает и такие аллокаторы для себя я пишу на С.
А зачем вы пишите их на С++ ? В микроконтроллерах обычно С++ не нужен.

Цитата Сообщение от Signum7 Посмотреть сообщение
Ну во-первых я экспериментирую с данными функциями
Так никто же не против. Просто раз вы опубликовали код на форуме то вы ждёте какой-то реакции. Пока у большинства реакция вида "что это такое?"

Цитата Сообщение от Signum7 Посмотреть сообщение
как раз интересно сравнить! и если есть профит так почему не использовать
зачем сравнивать некое время, затраченное на вызов аллокатора (malloc) с нулём (ибо линейный аллокатор не тратит время) ?
вы таким образом только тестируете сколько потреблет malloc, притом неправильно тестируете.

К вам все вопросы сводятся к тому что мы не понимаем что вы делаете и зачем. Вопросы к коду это так-мелочи.

Цитата Сообщение от Signum7 Посмотреть сообщение
Лучше давать рекомендации по функционалу и логике работы
Я например не могу представить для чего такой функционал нужен - соответственно не могу говорить об организации API? врутреннем устройстве и пр.
Вы что-то придумали а мы пока не догоняем.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.02.2024, 20:13

malloc vs. calloc
Когда стоит использовать malloc , а когда calloc?

calloc vs malloc
Объясните,пжлста,чем отличается malloc oт calloc?

Malloc / calloc
здравствуйте. Интересует такой вопрос : динамическая память. Когда мы выделяем память при помощи функции malloc то нас в универе учат...

Как string создает строку?(calloc, malloc)
стринг создает строку с помощью calloc, malloc?

malloc, realloc
У меня задан одномерный динамический массив таким образом: int *m1=new int; //n-количество элементов, вводится пользователем Далее этот...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
45
Ответ Создать тему
Новые блоги и статьи
Транслитерация текста с кириллицы на латиницу (вариант №2)
Maks 13.11.2026
Обновленная версия ранее созданной обработки. Добавлено: - Проверка исходного текста на кириллицу, через обращение к стандартной функции "ТолькоКириллицаВСтроке" из общего модуля. . .
Часы с термометром и праздничным календарем
yariko 12.11.2026
Сегодня мы рассмотрим как можно сделать отличные многофункциональные часы. Итак, поставим конкретную задачу: разработать часы с календарем, двумя термодатчиками, выводом поздравительных сообщений. . .
Транслитерация текста с кириллицы на латиницу (вариант №1)
Maks 11.11.2026
Решил облегчить жизнь себе и коллегам админам при создании электронных почтовых ящиков для пользователей, в результате написал обработку "Транслитерация текста" с кириллицы на латиницу, а в ней. . .
Книги по геймдизайну, левел-дизайну, игровым механикам и проектированию игрового опыта
8Observer8 08.11.2026
Содержание блога | English Version 1. 2003 - 06 - Designing Virtual Worlds (1st Edition) Автор: Richard A. Bartle | Объем: 768 стр. Ссылки: Amazon . . .
Родители токсичные абьюзеры по отношению к своим детям ругают их оскорбляют не любят
zorxor 08.11.2026
Жить в атмосфере постоянных оскорблений, критики и холодности со стороны родителей — это тяжелое и болезненное испытание, которое оставляет глубокие эмоциональные раны. Токсичное и абьюзивное. . .
Как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Ответ от Джемени ИИ.
zorxor 08.11.2026
Джемени, как только я захожу к себе в свою комнату я сразу же с себя снимаю свои трусы. Многие люди, возвращаясь домой, сразу переодеваются в максимально свободную одежду или вовсе предпочитают. . .
Паттерн очереди действий/команд (Action / Command Queue). Система очереди действий и кат-сцен с SDL3 Callbacks, cglm и OpenGL
8Observer8 07.11.2026
Содержание блога | English Version Руководство для начинающих по реализации паттерна очереди действий/ команд (Action / Command Queue) на C++ (C++20) с использованием официального SDL3 Callbacks. . .
Проверка полного ФИО в типовом справочнике
Maks 07.11.2026
Решение реализовано в конфигурации КА2, на примере справочника "КонтактныеЛицаПартнеров". Задача: Запрет инициалов. Не допускаеть использование сокращений вида "И. И. ", "И. И. ", "И И" и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru