Перейти к содержанию
    

Непонятное увеличение RAM

1 час назад, AndyBig сказал:

Память для массива с длиной, определяемой переменной, выделяется из HEAP. Со стеком ничего интересного не происходит, все стандартно

сейчас проверил.  Да, я зря был уверен) Действительно, память пытается выделиться из heap. Причем, подленько так, из дефолтной heap.

image.thumb.png.96d936a0146f11e3073837478ab330a9.png

  Вот отсюда вопрос, как сделать так чтобы подобные неявные вызовы malloc перенаправлялись в pvPortMalloc, например?

Изменено пользователем tgruzd

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

54 minutes ago, tgruzd said:

Вот отсюда вопрос, как сделать так чтобы подобные неявные вызовы malloc перенаправлялись в pvPortMalloc, например?

Не создавать ситуации с неявными вызовами динамического выделения и освобождения памяти, например 🙂 Если необходимо выделить динамически память - надо делать это осознанно и аккуратно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 минут назад, AndyBig сказал:

Если необходимо выделить динамически память - надо делать это осознанно и аккуратно.

это понятно.  Вопрос как раз в том, чтобы гарантированно исключить "неосознанное" выделение, как в ситуации выше.  Как  сделать хотя бы обертку для подобного вызова? 

#undef malloc
#define malloc    	custom_malloc

Так в данной ситуации не получится.

9 минут назад, AndyBig сказал:

Не создавать ситуации с неявными вызовами динамического выделения и освобождения памяти, например 🙂

Есть закрытый список таких ситуаций?

Изменено пользователем tgruzd

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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);
}

Простите, не нашел как сделать код сворачиваемым.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, jenya7 said:

с другой стороны - я опустил HEAP на ноль а проект компилируется.

Вы указали размер HEAP нулевым, но не убрали сам HEAP из файла конфигурпции линкера. В результате линкер не учитывает HEAP в итоговом размере оперативки. И, возможно, функции динамического выделения памяти не проверяют максимальный размер запрошенной памяти, но тут я не уверен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, tgruzd said:

Вопрос как раз в том, чтобы гарантированно исключить "неосознанное" выделение, как в ситуации выше.

Запретить VLA и использовать явные вызовы менеджера памяти с проверкой аргументов и результатов, а не как в примере из первого поста.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 часа назад, jenya7 сказал:

я опустил HEAP на ноль а проект компилируется

😂🤣😅

Цитата

Виктор Михайлович уцелел чудом и из обломков мотоцикла в следующий запойный период устроил стационарный двигатель, который был очень похож на настоящий, но не работал.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, Сергей Борщ сказал:

Переопределить malloc() своей реализацией, которая вызывает ваш любимый менеджер кучи? В gcc работает:

Сергей, спасибо. но немного не в том вопрос. Во первых, си без плюсов. Во-вторых, не гцц. В-третьих, для своего кода переопределить malloc - не проблема. Проблема, как я  её вижу,  переопределить malloc вызываемый неявно, например как здесь:

image.png.02a124a0446d1b0680d8b4a14c9d7a16.png

Нашёл такой файл, буду копать в эту сторону:

Спойлер
/* 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
 

 

 

Изменено пользователем tgruzd

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, tgruzd сказал:

Проблема, как я  её вижу,  переопределить malloc вызываемый неявно, например как здесь:

А разве там компилятор не вставляет вызов той же самой malloc()? Что говорит листинг?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 минут назад, Сергей Борщ сказал:

А разве там компилятор не вставляет вызов той же самой malloc()? Что говорит листинг?

Вставляет, как выяснилось.  Но не переопределенной, а дефолтной.  Ну или я переопределяю неправильно. 

7 часов назад, tgruzd сказал:

image.thumb.png.96d936a0146f11e3073837478ab330a9.png

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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;
}

 

image.thumb.png.830e109d863daa2b6651d0344b3a4741.png

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот у вас работает,  а у меня не работает:

image.png.3f7fb4ab9fe6d3ace700c80780af6711.png  

image.png.85828bf64dcc72f96a6554fc022e8972.png

 

 

Изменено пользователем tgruzd

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

24 minutes ago, tgruzd said:

а у меня не работает

А где у вас здесь переопределение функции malloc()?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 минут назад, AndyBig сказал:

А где у вас здесь переопределение функции malloc()?

Аааа!  Hеправильно я всё делал. Не нужно было макросы лепить. Сделал функцию (а чё, так можно было?🤣), теперь всё работает как надо (ну или выглядит так). Выставил Heap_Size в ноль, из .sct убрал секцию HEAP - РАБОТАЕТ!!! Спасибо!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...