Вопросы от "чайника" - страница 107

 
mql5:
Деструкторы в MQL5 всегда виртуальные. Удаляется всё правильно, попробуйте проставить Print(__FUNCSIG__); в деструкторах.


Я это делал в VC++, но механизмы освобождения памяти думаю одинаковы?
Документация по MQL5: Основы языка / Операторы / Оператор уничтожения объекта delete
Документация по MQL5: Основы языка / Операторы / Оператор уничтожения объекта delete
  • www.mql5.com
Основы языка / Операторы / Оператор уничтожения объекта delete - Документация по MQL5
 
220Volt:
Я это делал в VC++, но механизмы освобождения памяти думаю одинаковы?
Нет, в С++ для правильного удаления объекта через delete обязательно указывать виртуальный деструктор.

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

Попробую высказать идею немного по-другому:

Дано:

  • Класс №1 - он весь занимает в памити 100 байт.
  • Класс №2 - он наследник класса №1, занимает в памяти 200 байт.
  • Указатель на класс №1.

Действия:

  • Записываем в указатель адрес участка памяти, в котором расположился экземпляр класса №2 (вызвали new)
  • Освобождаем участок паяти, передавая функции delete адрес, хранимый в указателе.

P.S: на рисунке модель памяти )

 
Сомнения потому что указатель на класс номер один, а фактически в памяти класс номер два. Ведь в случаи с деструкторами это имеет значение, вот я и подумал, а вдруг и здесь может быть проблема. Думаю что в подобной ситуации правильное освобождение памяти может произойти только если в памяти есть какие-то метки (как char с нуль-терминатором) или что-то вроде, поэтому и спрашивал про то как выделяется память.
 
220Volt:
Сомнения потому что, указатель на класс номер один, а фактически в памяти класс номер два. Ведь в случаи с деструкторами это имеет значение, вот я и подумал, а вдруг и здесь может быть проблема. Думаю что в подобной ситуации правильное освобождение памяти может произойти только если в памяти есть какие-то метки (как char с нуль-терминатором) или что-то вроде, поэтому и спрашивал про то как выделяется память.

Ваше сомнение от того что вы не прописали конструкторы (для понимания что происходит в данном случае это важно), попробуйте запустить вот этот пример, и вы всё поймёте:

class CFoo
  {
public:
                     CFoo() { Print(__FUNCSIG__); }
                    ~CFoo() { Print(__FUNCSIG__); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
class CBar : public CFoo
  {
public:
                     CBar() { Print(__FUNCSIG__); }
                    ~CBar() { Print(__FUNCSIG__); }
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {
   CFoo *f=new CBar();

   delete f;
  }
//+------------------------------------------------------------------+

ЗЫ само конструирование как и удаление происходит ступеньчато, и вся эта информация хранится(сам виртуальный указатель помнить что класс был сконструирован как составной от базового и потомка), и при удалении происходит вызов деструкторов в обратном порядке, от более позднего к более раннему.

 
Дело не в деструкторах, они не главное, дело в самом классе, а точнее в том какое количество байт он занимает. Получается так что мы выделяем 200 байт, а потом гоорим освободи мне память на которую указывает указатель, представляющий объект размером 100 байт.
 
220Volt:
Дело не в деструкторах, они не главное, дело в самом классе, а точнее в том какое количество байт он занимает. Получается так что мы выделяем 200 байт, а потом гоорим освободи мне память на которую указывает указатель, представляющий объект размером 100 байт.
Я так понимаю Ваш вопрос связан с особенностями работы пула памяти.
Да пул памяти знает какой длины кусок будет освобождаться вызовом delete.
Где хранится эта информация зависит от реализации пула.

Например в если Вы в С++ отдадите указатель на объект который не выделялся через new, то увидите, как Ваше приложение завершится крахом.
 
220Volt:
Дело не в деструкторах, они не главное, дело в самом классе, а точнее в том какое количество байт он занимает. Получается так что мы выделяем 200 байт, а потом гоорим освободи мне память на которую указывает указатель, представляющий объект размером 100 байт.
Я так понял ты мой пример не запускал. Иначе бы таких вопросов не было бы.
 
Я подумал, вспомнил о том что можно выделить память под массив например int'ов а потом удалить все, не смотря на то что один инт маленький, наверное также и с классами. Спасибо за ответы.
 
mql5:
Я так понимаю Ваш вопрос связан с особенностями работы пула памяти.
Да пул памяти знает какой длины кусок будет освобождаться вызовом delete.
Где хранится эта информация зависит от реализации пула.

Например в если Вы в С++ отдадите указатель на объект который не выделялся через new, то увидите, как Ваше приложение завершится крахом.
Вот, примерно о том, спасибо.
Причина обращения: