Вопросы по С/С++ (СИ)
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Шаблон тут не спасёт. Шаблон - это, как бы Вам проще объяснить, некая заготовка, не имеющая конкретного типа данных. Он (тип) определяется с объявлением объекта по этому шаблону.
Вопрос по Вашему сабжу. А что Вам мешает, удалив необходиый Node из списка, удалить данные, связанные с ним ? Ссылку то на данные имеете.
Вопрос по Вашему сабжу. А что Вам мешает, удалив необходиый Node из списка, удалить данные, связанные с ним ? Ссылку то на данные имеете.
- Реклама
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Alex
Просто хотел подчистить код, в котором применяется класс QLIST.
Типа, чтобы строкой
удалялись из памяти все ноды и данные с ними связанные.
Проблема в том, что под void указателем может скрываться что угодно.
А этот класс используется для формирования списков данных различного типа.
Только с условием: один список - один тип данных для всех нодов данного списка.
А на данный момент это выглядит так:
где childList является объектом класса QLIST.
Это деструктор класса Widget. При удалении виджета, удаляются все его дочерние виджеты.
После выхода из деструктора виджета вызывается деструктор объекта childList автоматически.
Хотя наверное это неправильно и в конструкторе класса Widget надо бы создать объект childList оператором new
и в деструкторе виджета удалить вручную childList оператором delete. Или не стоит заморачиваться?
Но по крайней мере, трассировка кучи не обнаруживает утечек памяти.
Просто хотел подчистить код, в котором применяется класс QLIST.
Типа, чтобы строкой
Код: Выделить всё
delete childList;
Проблема в том, что под void указателем может скрываться что угодно.
А этот класс используется для формирования списков данных различного типа.
Только с условием: один список - один тип данных для всех нодов данного списка.
А на данный момент это выглядит так:
Код: Выделить всё
Widget::~Widget()
{
Widget *pC = 0;
childsList.pointer_begin();
while(childsList.get_data_next((void**)&pC) == true)
{
delete pC;
}
}
Это деструктор класса Widget. При удалении виджета, удаляются все его дочерние виджеты.
После выхода из деструктора виджета вызывается деструктор объекта childList автоматически.
Хотя наверное это неправильно и в конструкторе класса Widget надо бы создать объект childList оператором new
и в деструкторе виджета удалить вручную childList оператором delete. Или не стоит заморачиваться?
Но по крайней мере, трассировка кучи не обнаруживает утечек памяти.
I am DX168B and this is my favourite forum on internet!
Re: Вопросы по С/С++ (СИ)
Плюсы-же - пусть объект сам о себе заботится:
Конструктор не обязателен - но инициализация лишней не бывает - а то позабытый случайно на стеке объект бабахнет на мусорном адресе при неявной деструкции.DX168B писал(а):Код: Выделить всё
typedef struct _tag_Node { _tag_Node() : nodeId(-1), next(NULL), prev(NULL), ptr(NULL) { } ~_tag_Node() { delete ptr; } long int nodeId; Node *next; Node *prev; void *ptr; } Node, *pNode;
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Заведите базовый объект для всех используемых типов - а потом вдарьте по ним полиморфизмом!DX168B писал(а):Проблема в том, что под void указателем может скрываться что угодно.
Либо взять уже готовый стандартный std::list либо изобрести такой-же my_list вручную.DX168B писал(а):Только с условием: один список - один тип данных для всех нодов данного списка.
Я бы сказал деструктор объекта childList вызывается неявно [как и для всех не-динамических полей класса] в ходе исполнения деструктора самого класса. И да, никакой неправильности в его не-динамичности нет - место будет выделено в области данных самого объекта класса - т.е. вместо двух объектов в куче (класс и список) вы поимеете один объект. Когда жизнь заставит разобираться с операторами присвоения объектов класса - динамические поля тоже потребуют к себе несколько завышенного внимания, чтобы впредь стараться обходиться без них.DX168B писал(а):После выхода из деструктора виджета вызывается деструктор объекта childList автоматически.
Хотя наверное это неправильно и в конструкторе класса Widget надо бы создать объект childList оператором new.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Я в курсе. Поля структуры у меня все равно заполняются сразу же после создания.Конструктор не обязателен - но инициализация лишней не бывает - а то позабытый случайно на стеке объект бабахнет на мусорном адресе при неявной деструкции.
Создаются они у меня в методах ::add(), ::insert() и в ::add_sort()
Вне класса я ничего со структурой не делаю. Все происходит внутри класса QLIST. Как рождение так и смерть этих структур.
Потому я и не заморачивался с конструкторами в структуре.
В конструкторе класса Widget, к примеру, вся инициализация есть.
Код: Выделить всё
//////////////////////////////////////////////////////////////////
// GUI wiget base class (inherited from GuiObject)
Widget::Widget()
{
drawContext.xPos = 0;
drawContext.yPos = 0;
drawContext.zPos = 0;
drawContext.xSize = 0;
drawContext.ySize = 0;
drawContext.zSize = 0;
drawContext.objectID = 0;
drawContext.extContext = 0;
drawContext.extContextType = DRAW_EXTENDED_CONTEXT_TYPE_NONE;
enableFlag = true;
focusFlag = true;
renderFunc = 0;
eventCallBack = 0;
}
виджетами рулят внешние скрипты. Конечно, можно все инициализации структуры drawContext вынести в конструктор структуры,
что было бы правильнее, так как над ней проводятся операции и вне класса Widget. Так и сделаю. Спасибо за наводку.
Подумываю над этим. Что-то придется переделать.Заведите базовый объект для всех используемых типов - а потом вдарьте по ним полиморфизмом!
Я просто поинтересовался, можно ли сделать это более изящно, чем то, что у меня сейчас есть.
Ну, свой лист я создавал не просто так. Дело в том, что по этому списку производится рендеринг, по нему же идет переборЛибо взять уже готовый стандартный std::list либо изобрести такой-же my_list вручную.
при передачи событий объектам. Рендеринг объектов должен производиться в особом порядке из-за особенностей OpenGL.
И этот порядок динамически изменяется под действием кучи параметров.
А std::list у меня уже используется в других местах.
Да уж стараюсь поменьше плодить динамических сущностей. Ибо это бьет как по надежности, так и по производительности.Я бы сказал деструктор объекта childList вызывается неявно [как и для всех не-динамических полей класса] в ходе исполнения деструктора самого класса. И да, никакой неправильности в его не-динамичности нет - место будет выделено в области данных самого объекта класса - т.е. вместо двух объектов в куче (класс и список) вы поимеете один объект. Когда жизнь заставит разобираться с операторами присвоения объектов класса - динамические поля тоже потребуют к себе несколько завышенного внимания, чтобы впредь стараться обходиться без них.
И после дебага всегда проверяю логи по утечкам. Собственно, у меня и был вопрос по механизмам освобождения памяти.
Просто небыло понятно про неявный вызов деструктора childList. Это типа стандарт, или особенность одного компилятора?
Просто сейчас это пишется в Visual Studio 2010, потом будет переезжать на GCC, когда будет портироваться под Linux.
Код: Выделить всё
~_tag_Node() { delete ptr; } Просто удаление объектов происходит одним способом, а удаление, допустим, строк (массивов) другим способом.
Ну, типа void может ссылаться как объект класса так и на обычную строку. А этот самопальный класс у меня используется и для списков строк, а в некоторых случаях и для отдельной строки. По символу на ноду. Просто в OpenGL рендеринг динамического текста - тот еще секас.
I am DX168B and this is my favourite forum on internet!
- Реклама
Re: Вопросы по С/С++ (СИ)
Ну т.е. он ещё и сортируется время от времени? В STL, кстати, алгоритмы есть разные - в т.ч. с заданием критериев обработки. Пока непонятно в чем преимущество самопального списка.DX168B писал(а):Рендеринг объектов должен производиться в особом порядке из-за особенностей OpenGL.
И этот порядок динамически изменяется под действием кучи параметров.
Вызов деструктора для не-динамических объектов - обязанность компилятора, либо по выходу из блока в котором он был объявлен, либо по уничтожению объекта-владельца как в описываемом случае.DX168B писал(а):Просто небыло понятно про неявный вызов деструктора childList. Это типа стандарт, или особенность одного компилятора?
Просто сейчас это пишется в Visual Studio 2010, потом будет переезжать на GCC, когда будет портироваться под Linux.
В данном случае никакой информации об объекте нету - и даже если скомпилирует без предупреждений-ошибок - всё, скорее всего сведётся к вызову free для освобождения указуемого блока памяти. Если же указывается объект - то будет исполнен его деструктор - даже если тип этого указателя - абстрактный базовый. Для удаления массивов выделенных посредством new[] хорошо не забывать использовать delete[] - ибо деструкторы всех элементов жаждут исполнения. А для строк есть std::string.DX168B писал(а):А корректно ли поведет себя оператор delete в этом случае?Код: Выделить всё
~_tag_Node() { delete ptr; }
Просто удаление объектов происходит одним способом, а удаление, допустим, строк (массивов) другим способом.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Минимализм. Пробовал различные варианты. При большом количестве объектов жутко проседает FPS.Пока непонятно в чем преимущество самопального списка.![]()
Это еще сильнее проявится, когда этот код заработает на Paspberry Pi.
Самопалом я добился нужного функционала за существенно меньшее количество операций.
Это просто узкое место в программе и тут производительность играет большую роль.
I am DX168B and this is my favourite forum on internet!
-
Pnjom-Penb
- Мучитель микросхем
- Сообщения: 469
- Зарегистрирован: Вс авг 30, 2015 03:52:59
Re: Вопросы по С/С++ (СИ)
Про использование иерархии классов для хранения разных наборов данных уже говорили выше, а чтобы корректно отрабатывал delete, нужно объявить деструктор базового класса виртуальным. В этом случае деструктор базового класса автоматически вызывается после деструктора производного класса.DX168B писал(а):А корректно ли поведет себя оператор delete в этом случае?
Re: Вопросы по С/С++ (СИ)
Угу, ПМСМ, std::list из указателей на объекты столь-же "удобен" в использовании как и имеющаяся C-style реализация, а не-динамические объекты в нём держать - на копированиях разориться можно. Попробуйте свою реализацию ошаблонить, используя в качестве параметра тип хранимого объекта - разницы в производительности не будет, ну разве что программу кратно числу разных типов параметров шаблона раздует слегка. А позднее связывание на скорости скажется в худшую сторону.DX168B писал(а):Пробовал различные варианты. При большом количестве объектов жутко проседает FPS.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Siarzhuk
Вот как раз ошаблонить этот класс я и собирался. А то, что его "раздует" на количество применяемых типов - так это некритично.
Правда, с шаблонами разбираться придется.
Вот как раз ошаблонить этот класс я и собирался. А то, что его "раздует" на количество применяемых типов - так это некритично.
Правда, с шаблонами разбираться придется.
I am DX168B and this is my favourite forum on internet!
Re: Вопросы по С/С++ (СИ)
Сделайте копию QLIST, работающую с одним из типов объектов, минимизируйте интерфейс либо поместив функции обработчики QLIST в отдельный модуль либо сделав их членами класса QLIST, а как всё соберётся и заработает - на основе этого модуля/класса сделайте шаблон и окончательно используйте его для других типов.DX168B писал(а):Правда, с шаблонами разбираться придется.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Там всё просто.DX168B писал(а):Правда, с шаблонами разбираться придется.
Шаблон позволяет определять тип данных, используемых в объекте, во время объявления этого объекта.
Например:
Код: Выделить всё
struct Node{
...
...
type_data Data;
};
В таком случае, создаёте шаблон, типа :
Код: Выделить всё
template <typename type_data> struct Node{
...
...
type_data Data;
};
Например :
Код: Выделить всё
Node <int> node;
Шаблон огораживает создание вручную кучу одинаковых экземпляров с разными типами, создавая автоматически отдельный экземпляр со своим типом, при объявлении объекта.
- DX168B
- Друг Кота
- Сообщения: 4468
- Зарегистрирован: Вс янв 24, 2010 19:19:52
- Откуда: Главный Улей России (Moscow)
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Alex
ОК. Понял. Разберусь. Ошаблонивать придется и класс QLIST, чтобы выбросить из него void указатели. (некоторые методы имеют в принимаемых аргументах аналогичные указатели) Тогда я смогу смело
сносить привязанные данные в деструкторе класса QLIST, а за тем и сами ноды.
Более того, данные я смогу сносить прямо в деструкторе удаляемой ноды, таким макаром:
и оператор delete отработает нормально, так как тип определен шаблоном при инициализации.
То что надо. Спасибо за подсказки.
ОК. Понял. Разберусь. Ошаблонивать придется и класс QLIST, чтобы выбросить из него void указатели. (некоторые методы имеют в принимаемых аргументах аналогичные указатели) Тогда я смогу смело
сносить привязанные данные в деструкторе класса QLIST, а за тем и сами ноды.
Более того, данные я смогу сносить прямо в деструкторе удаляемой ноды, таким макаром:
Код: Выделить всё
~_tag_Node() { delete ptr; } То что надо. Спасибо за подсказки.
I am DX168B and this is my favourite forum on internet!
Re: Вопросы по С/С++ (СИ)
Здоровья всем! Вопрос по С.
Есть массив arr, забитый из ЕЕПРОМа и переменная tot.Эта переменная может иметь разные изменяемые значения от 2 до длины массива (16).
Подскажите, как более-менее равномерно распределить данные из этого массива, например в другой массив размером с tot? Понятно, когда 16 кратно значению tot. А в других случаях? И желательно по минимуму затрагивать arr[0].
Есть массив arr, забитый из ЕЕПРОМа и переменная tot.
Код: Выделить всё
uint_fast8_t arr[16]={0,45,8,120,18,24,32,64,90,126,147,168,200,255,33,56};
uint_fast8_t tot;Подскажите, как более-менее равномерно распределить данные из этого массива, например в другой массив размером с tot? Понятно, когда 16 кратно значению tot. А в других случаях? И желательно по минимуму затрагивать arr[0].
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Какие то мысли вслух, а не вопрос. Ничего не понятно...
Re: Вопросы по С/С++ (СИ)
Аlex, прошу прощения.
К примеру, если tot==8, то из массива arr выбирается каждая вторая запись и копируется в другой массив, размерностью = 8 байт.
Если tot==4, то из массива arr выбирается каждая четвертая запись и копируется в другой массив, размерностью = 4 байт. Т.о. выборки из массива arr распределятся по всей его длине. И вопрос: как это дело(распределение выборок) поумнее схимичить, если tot получился, к примеру = 7 или там 11...?
К примеру, если tot==8, то из массива arr выбирается каждая вторая запись и копируется в другой массив, размерностью = 8 байт.
Если tot==4, то из массива arr выбирается каждая четвертая запись и копируется в другой массив, размерностью = 4 байт. Т.о. выборки из массива arr распределятся по всей его длине. И вопрос: как это дело(распределение выборок) поумнее схимичить, если tot получился, к примеру = 7 или там 11...?
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Ну, в случае с 4 или 8, то тут понятно - делим просто на это число и всё.
А вот с "нестандартными" значениями - тут, как бы, и нам не понятно, что Вы хотите.
А вот с "нестандартными" значениями - тут, как бы, и нам не понятно, что Вы хотите.
Re: Вопросы по С/С++ (СИ)
Ну плин...
Аlex троллите что ли? Фуф. Попробую "на пальцах". Есть у Вас веревка/нитка... длиной = размерности(длине) массива arr. То бишь 16 условных метров. Нужно сложить ее в tot максимально одинаковых кусков. Значение tot может быть разным от 2 до 16. Так понятнее?
Вот как раскидать tot выборок по массиву, по возможности равномерно? С флоатом связываться не хочется, для 2 килобайт флеша это жирновато будет.
- Аlex
- Модератор
- Сообщения: 4614
- Зарегистрирован: Чт мар 18, 2010 23:09:57
- Откуда: Планета Земля
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Не, не трлллю, честно 
Просто мне действительно не понятно, как выбирать значения, если, например, будет число 9.
Просто, для примера, назовите выборки для tot = 9.
Просто мне действительно не понятно, как выбирать значения, если, например, будет число 9.
Просто, для примера, назовите выборки для tot = 9.
Re: Вопросы по С/С++ (СИ)
Так и мне непонятно, оттого и спросил.))
Воот. Получается, в основном, выборка будет через одну ячейку массива(0,2,4...), а где-то указатель должен попасть и на следующую, за выбранной, ячейку. Что-то типа: 1,3,5,7,9,10,12,14,15. (Нулевую ячейку, по возможности, не трогать). Вот как схимичить эту автоматику?для примера, назовите выборки для tot = 9


