Будет ли тут утечка памяти
- Войдите на сайт для отправки комментариев
Ср, 15/04/2020 - 14:14
День добрый.
В своем скетче я объявляю структуру, которую у меня будут возвращать многие функции:
struct TResult
{
int ErrorCode;
String ErrorDescription;
};
К примеру, функция:
TResult SaveSettings()
{
TResult result = {0, ""};
// разные полезные дела
return result;
}
И вот так я буду ее вызывать:
TResult SaveSettingsResult = SaveSettings();
ReturnResultToHost(&SaveSettingsResult);
где:
void ReturnResultToHost(struct TResult *result)
{
SendToHost("rsl:КодОшибки=" + String(result->ErrorCode) + "|" + "ОписаниеОшибки=" + result->ErrorDescription);
}
Я пришел из Дельфи, где эту структуру я бы разместил в стеке и среда позаботилась бы о ней.
Позаботится ли о ней среда Arduino?
Правильней будет - "Позаботится ли о ней компилятор Си". Нет, не позаботится. До тех пор, пока TResult не будет обладать всеми методами копирования содержимого (см. класс String), результат работы SaveSettings() наврядли можно будет назвать предсказуемым.
у структуры по умолчанию есть конструктор побитного копирования, не надо заботиться, покуда она указатели не хранит.
В структуре есть String. В си это указатель вроде.
Вот эта строчка кода
TResult SaveSettingsResult = SaveSettings();
Вызовет ли она создание новой структуры TResult, пустой, в которую потом запишется результат функции?
Если да, что будет с результатом функции? Он освободит свою занятую память?
Что будет дальше со структурой SaveSettingsResult после выхода из основной процедуры?
у структуры по умолчанию есть конструктор побитного копирования, не надо заботиться, покуда она указатели не хранит.
То есть компилятор без потерь отработает struct someStruct_t someStruct = makeFoolWork(), где struct someStruct_t makeFoolWork() но за счет временного оверхеда по памяти? Мне ООП в МК не особо нужен, так что я не интересовался. Возврат указателей на разные там локально объявленные массивы - потенциально бажный.
Пишу для Arduino DUE, в которой нет замера свободной ОЗУ, но где то валялась UNO, под которую сейчас тесты загоню, проверим.
Пишу для Arduino DUE, в которой нет замера свободной ОЗУ
Всё там есть.
Можно увидеть код, который покажет свободный размер ОЗУ?
Можно увидеть код, который покажет свободный размер ОЗУ?
Под Due? Вот:
#include <malloc.h> #include <stdlib.h> #include <stdio.h> int freeRam() { struct mallinfo mi = mallinfo(); char* heapend = _sbrk(0); register char* stack_ptr asm("sp"); return (stack_ptr - heapend + mi.fordblks); }Проверил, вроде не течет.
Добавил мониторинг памяти в лог
В структуре есть String. В си это указатель вроде.
А вот те хрен. Это в Дельфи любой экземпляр класса создается в куче и ты неявно работаешь с указателями, зачастую даже ничего об этом не подозревая. В Си, все локальные переменные-экземпляры честно создаются как временные, на стеке и при выходе из области видимости (читай, как функция кончится) автоматически вызывается деструктор (ну, если он есть, канеш). Если ты в своем классе, созданном локально, не хапал память из кучи, ничего не потечет, но члены-указатели могут попортиться, если были.
Ардуино программируют на C++, а не C. В C++ есть деструкторы, перегрузка операторов присвоения, и прочее, что решит проблему в данном случае.
В С все это давно решили, когда разрешили возвращать нетривиальные типы из функций. Если коротко ответить, то утечки не будет, если долго и действительно интересно - спросите.
В C вообще нет разделения тривиальный-нетривиальный. Там даже классов нет, к которым относится это разделение.
Читал всякое, наткнулся на небольшое исследование, решил поделиться в этой теме:
"Возврат структуры из функции в C++" : https://dev64.wordpress.com/2012/10/11/object-return-in-cpp/
Кратко: возвращается нормально, в ряде случаев без оверхеда.