gridinp 3 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба а, невнимательно смотрел Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 22 декабря, 2022 Опубликовано 22 декабря, 2022 (изменено) · Жалоба 1 час назад, AndyBig сказал: Память для массива с длиной, определяемой переменной, выделяется из HEAP. Со стеком ничего интересного не происходит, все стандартно сейчас проверил. Да, я зря был уверен) Действительно, память пытается выделиться из heap. Причем, подленько так, из дефолтной heap. Вот отсюда вопрос, как сделать так чтобы подобные неявные вызовы malloc перенаправлялись в pvPortMalloc, например? Изменено 22 декабря, 2022 пользователем tgruzd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AndyBig 8 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 54 minutes ago, tgruzd said: Вот отсюда вопрос, как сделать так чтобы подобные неявные вызовы malloc перенаправлялись в pvPortMalloc, например? Не создавать ситуации с неявными вызовами динамического выделения и освобождения памяти, например 🙂 Если необходимо выделить динамически память - надо делать это осознанно и аккуратно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 22 декабря, 2022 Опубликовано 22 декабря, 2022 (изменено) · Жалоба 9 минут назад, AndyBig сказал: Если необходимо выделить динамически память - надо делать это осознанно и аккуратно. это понятно. Вопрос как раз в том, чтобы гарантированно исключить "неосознанное" выделение, как в ситуации выше. Как сделать хотя бы обертку для подобного вызова? #undef malloc #define malloc custom_malloc Так в данной ситуации не получится. 9 минут назад, AndyBig сказал: Не создавать ситуации с неявными вызовами динамического выделения и освобождения памяти, например 🙂 Есть закрытый список таких ситуаций? Изменено 22 декабря, 2022 пользователем tgruzd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 1 час назад, tgruzd сказал: Вот отсюда вопрос, как сделать так чтобы подобные неявные вызовы malloc перенаправлялись в pvPortMalloc, например? Переопределить malloc() своей реализацией, которая вызывает ваш любимый менеджер кучи? В gcc работает: extern "C" void * malloc(size_t size) { return Manager.malloc(size); } #include <string.h> extern "C" void * calloc(size_t count, size_t element_size) { void * Ptr = malloc(count * element_size); if(Ptr) memset(Ptr, 0, count * element_size); return Ptr; } extern std::nothrow_t const std::nothrow; void * operator new(size_t size, std::nothrow_t const &) { return Manager.malloc(size); } void * operator new[](size_t size, std::nothrow_t const &) { return Manager.malloc(size); } void * operator new(size_t size) { void * Ptr; while((Ptr = Manager.malloc(size))== nullptr) free_memory(); return Ptr; } void * operator new[](size_t size) { return operator new(size); } extern "C" void free(void * ptr) { Manager.free(ptr); } void operator delete(void * ptr) // delete allocated storage { free(ptr); } // absence of this implementation causes warning since C++14. // Called instead of operator delete(void *) if a user-defined replacement is provided, except that it's // unspecified whether operator delete(void *) or operator delete(void *, size_t) is called when deleting // objects of incomplete type and arrays of non-class and trivially-destructible class types. A memory allocator // can use the given size to be more efficient. The standard library implementations are identical to operator delete(void *) void operator delete(void * ptr, size_t) { free(ptr); } void operator delete[](void * ptr) // delete allocated storage { free(ptr); } // absence of this implementation causes warning since C++14. // Called instead of operator delete[](void *) if a user-defined replacement is provided, except that it's // unspecified whether operator delete[](void *) or operator delete[](void *, size_t) is called when deleting // objects of incomplete type and arrays of non-class and trivially-destructible class types. A memory allocator // can use the given size to be more efficient. The standard library implementations are identical // to operator delete[](void *) void operator delete[](void * ptr, size_t) { free(ptr); } Простите, не нашел как сделать код сворачиваемым. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AndyBig 8 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 3 hours ago, jenya7 said: с другой стороны - я опустил HEAP на ноль а проект компилируется. Вы указали размер HEAP нулевым, но не убрали сам HEAP из файла конфигурпции линкера. В результате линкер не учитывает HEAP в итоговом размере оперативки. И, возможно, функции динамического выделения памяти не проверяют максимальный размер запрошенной памяти, но тут я не уверен. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AndyBig 8 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 3 minutes ago, tgruzd said: Вопрос как раз в том, чтобы гарантированно исключить "неосознанное" выделение, как в ситуации выше. Запретить VLA и использовать явные вызовы менеджера памяти с проверкой аргументов и результатов, а не как в примере из первого поста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 4 часа назад, jenya7 сказал: я опустил HEAP на ноль а проект компилируется 😂🤣😅 Цитата Виктор Михайлович уцелел чудом и из обломков мотоцикла в следующий запойный период устроил стационарный двигатель, который был очень похож на настоящий, но не работал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 22 декабря, 2022 Опубликовано 22 декабря, 2022 (изменено) · Жалоба 6 часов назад, Сергей Борщ сказал: Переопределить malloc() своей реализацией, которая вызывает ваш любимый менеджер кучи? В gcc работает: Сергей, спасибо. но немного не в том вопрос. Во первых, си без плюсов. Во-вторых, не гцц. В-третьих, для своего кода переопределить malloc - не проблема. Проблема, как я её вижу, переопределить malloc вызываемый неявно, например как здесь: Нашёл такой файл, буду копать в эту сторону: Спойлер /* rt_heap.h: definitions to enable retargetting of heap implementation * * Copyright 1999 ARM Limited. All rights reserved. * * RCS $Revision$ * Checkin $Date$ * Revising $Author$ */ #ifndef __RT_HEAP_H #define __RT_HEAP_H #define __ARMCLIB_VERSION 6190004 #include <stdint.h> #include <stddef.h> #ifdef __cplusplus extern "C" { #endif /* * This is the structure that defines the heap descriptor. The * first section of it is used by the C library and so the format * is fixed. Space after that can be used as the user wishes. */ struct __Heap_Descriptor; /* * Define all these functions to override the heap. __Heap_DescSize * must return the size of the __Heap_Descriptor structure. */ extern int __Heap_DescSize(int zero); extern void __Heap_Initialize(struct __Heap_Descriptor *h); extern void __Heap_Finalize(struct __Heap_Descriptor *h); extern void __Heap_ProvideMemory(struct __Heap_Descriptor *, void *, size_t); extern void *__Heap_Alloc(struct __Heap_Descriptor *, size_t); extern void __Heap_Free(struct __Heap_Descriptor *, void *); extern void *__Heap_Realloc(struct __Heap_Descriptor *, void *, size_t); extern void *__Heap_Stats(struct __Heap_Descriptor *, int (* /*print*/)(void *, char const *format, ...), void * /*printparam*/); extern int __Heap_Valid(struct __Heap_Descriptor *, int (* /*print*/)(void *, char const *format, ...), void * /*printparam*/, int /*verbose*/); /* * The heap can call these functions when it is full or * inconsistent. __Heap_Full is passed the extra size that the heap * needs, and will call back to __Heap_ProvideMemory if it can find * some more storage. These are not functions you should override. */ extern int __Heap_Full(struct __Heap_Descriptor *, size_t); extern void __Heap_Broken(struct __Heap_Descriptor *); /* * Call _init_alloc, and define __rt_heap_extend, if you are trying * to run a heap on the bare metal. */ extern void _init_alloc(uintptr_t /*base*/, uintptr_t /*top*/); extern size_t __rt_heap_extend(size_t /*size*/, void ** /*block*/); #ifdef __cplusplus } #endif #endif Изменено 22 декабря, 2022 пользователем tgruzd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 4 минуты назад, tgruzd сказал: Проблема, как я её вижу, переопределить malloc вызываемый неявно, например как здесь: А разве там компилятор не вставляет вызов той же самой malloc()? Что говорит листинг? 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 5 минут назад, Сергей Борщ сказал: А разве там компилятор не вставляет вызов той же самой malloc()? Что говорит листинг? Вставляет, как выяснилось. Но не переопределенной, а дефолтной. Ну или я переопределяю неправильно. 7 часов назад, tgruzd сказал: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AndyBig 8 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 1 hour ago, tgruzd said: Ну или я переопределяю неправильно. Да вроде работает переопределение: void * malloc(uint32_t size) { return 0; } int main() { while (1) { if (len > 2) func(len*2); } } uint32_t func(uint32_t abc) { uint32_t ret; uint32_t str_len = abc/2; // char *string = new char[str_len]; char string[str_len]; ret = strlen(string); return ret; } 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 22 декабря, 2022 Опубликовано 22 декабря, 2022 (изменено) · Жалоба Вот у вас работает, а у меня не работает: Изменено 22 декабря, 2022 пользователем tgruzd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AndyBig 8 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 24 minutes ago, tgruzd said: а у меня не работает А где у вас здесь переопределение функции malloc()? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tgruzd 11 22 декабря, 2022 Опубликовано 22 декабря, 2022 · Жалоба 17 минут назад, AndyBig сказал: А где у вас здесь переопределение функции malloc()? Аааа! Hеправильно я всё делал. Не нужно было макросы лепить. Сделал функцию (а чё, так можно было?🤣), теперь всё работает как надо (ну или выглядит так). Выставил Heap_Size в ноль, из .sct убрал секцию HEAP - РАБОТАЕТ!!! Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться