Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Разное > Флейм
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #31  
Старый 30.03.2014, 23:26
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от angvelem
А ты посмотри модуль system.pas и поймёшь, что никакой утечки не будет.
Простой пример:
Код:
type
  TMyObject = class
  private
    FMem: Pointer;
  public
    constructor Create(MemSize: Integer = 8192);
    destructor Destroy; override;
    property Mem: Pointer read FMem;
  end;

constructor TMyObject.Create(MemSize: Integer);
begin
  GetMem(FMem, MemSize);
end;

destructor TMyObject.Destroy;
begin
  FreeMem(FMem);
  ShowMessage(ClassName + '.Destroy');
  inherited;
end;

procedure TMainForm.Button1Click(Sender: TObject);
var
  MyArray: array of TMyObject;
begin
  SetLength(MyArray, 2);
  MyArray[1] := TMyObject.Create;
  SetLength(MyArray, 1);
  MyArray[0] := TMyObject.Create;
end;
Вешаем обработчик на кнопку, запускаем диспетер задач, тыкаем, наслаждаемся.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #32  
Старый 31.03.2014, 00:01
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

При неправильном подходе к задаче, можно долго наслаждаться чем угодно и как угодно. Постоянно путаешь выделение памяти и объекты.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #33  
Старый 31.03.2014, 00:23
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от Freeman
Простой пример:
Код:
.....
procedure TMainForm.Button1Click(Sender: TObject);
var
  MyArray: array of TMyObject;
begin
  SetLength(MyArray, 2);
  MyArray[1] := TMyObject.Create;
  SetLength(MyArray, 1);
  MyArray[0] := TMyObject.Create;
end;
Вешаем обработчик на кнопку, запускаем диспетер задач, тыкаем, наслаждаемся.
Ну так такая же утечка памяти будет и со статическим массивом (без всяких SetLength):
Код:
procedure TMainForm.Button1Click(Sender: TObject);
var
  MyArray: array [0..1] of TMyObject;
begin
  MyArray[1] := TMyObject.Create;
  MyArray[0] := TMyObject.Create;
end;
Или даже вообще без массивов:
Код:
procedure TMainForm.Button1Click(Sender: TObject);
var
  MyObj0, MyObj1: TMyObject;
begin
  MyObj1 := TMyObject.Create;
  MyObj0 := TMyObject.Create;
end;
Повторю ещё раз - это не из-за того что массивы это зло, а из-за того, что объекты (экземпляры класса) не являются авторазрушаемыми сущностями из-за отсутствия у них механизма подсчёта ссылок (или чего нибудь типа того).

Или вот ещё небольшой пример того, почему разрушение массива не должно вызывать деструкторы объектов:
Код:
procedure TForm1.Button1Click(Sender: TObject);
var
  A: array of TEdit;
  i: Integer;
begin
  // Находим нужные элементы управления на форме и помещаем в массив ссылки на них:
  SetLength(A, FCount);
  for i := 1 to FCount do
  begin
    A[i] := (FindComponent('Edit'+IntToStr(i)) as TEdit);
  end;

  // Теперь через массив удобно работать с этими элементами управления.

  // А после выхода из этого обработчика динамический массив будет автоматически разрушен
  // и что если при этом он вызовет деструкторы элементов управления?
  // Они же пропадут с формы... Разве входило в планы разрушить интерфейс пользователю?
end;
Ответить с цитированием
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение:
Aristarh Dark (31.03.2014)
  #34  
Старый 31.03.2014, 08:22
Аватар для M.A.D.M.A.N.
M.A.D.M.A.N. M.A.D.M.A.N. вне форума
Sir Richard Abramson
 
Регистрация: 05.04.2008
Сообщения: 5,505
Версия Delphi: XE10
Репутация: выкл
По умолчанию

Как я понял из всего этого холивара, Фриман имеет ввиду, зачем разрешено в дельфи использовать дин. массивы для объектов и откуда взялась фишка давать в примерах использование оных для объектов.

Вот и вся суть холивара.
__________________
— Как тебя понимать?
— Понимать меня не обязательно. Обязательно меня любить и кормить вовремя.


На Delphi, увы, больше не программирую.
Рекомендуемая литература по программированию
Ответить с цитированием
Этот пользователь сказал Спасибо M.A.D.M.A.N. за это полезное сообщение:
Freeman (01.04.2014)
  #35  
Старый 31.03.2014, 18:30
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

а еще у Win32 Common Controls можно к элементам привязать указатели на объекты, которые тоже не освобождаются при удалении элемента. тоже запрещать что-ли?
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #36  
Старый 31.03.2014, 19:16
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

Да вообще указатели запретить... И все ЯВУ... Пусть на ассемблере пишут, а то зажрались...
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #37  
Старый 31.03.2014, 22:05
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
Да вообще указатели запретить... И все ЯВУ... Пусть на ассемблере пишут, а то зажрались
На ассемблере как раз ТОЛЬКО указатели жи.
Наоборот, запретить ассемблер, все ЯВУ, разрешить только жабу, C# и скрипты. Привет, андройд.
__________________
jmp $ ; Happy End!
The Cake Is A Lie.
Ответить с цитированием
  #38  
Старый 01.04.2014, 03:45
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от poli-smen
// А после выхода из этого обработчика динамический массив будет автоматически разрушен
// и что если при этом он вызовет деструкторы элементов управления?
// Они же пропадут с формы... Разве входило в планы разрушить интерфейс пользователю?
Я поэтому и говорил, что раз массивы объектов разрешены, нужно понятие владеющей и невладеющей ссылки. В TObjectList для этого есть OwnsObjects.

Цитата:
Сообщение от Bargest
запретить ассемблер, все ЯВУ, разрешить только жабу, C# и скрипты.
На самом деле это подмена понятий, внедренная в сознание масс разработчиков. Вместо того, чтобы упростить разработку на компилирумых языках, было предложено заменить это эрзацем управляемого кода (а теперь еще и скриптами), а удобство компиляторов так и застряло в прошлом веке.

Свою задачу как разработчика ЯП я вижу в восстановлении справедливости при сохранности природы компилируемого кода как таковой. В частности, вместо сборки мусора я хочу задействовать граф владения, использующий счетчик ссылок когда потребуется и вычисляемую еще на этапе компиляции достижимость объектов во всех остальных случаях.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #39  
Старый 01.04.2014, 08:40
Аватар для PhoeniX
PhoeniX PhoeniX вне форума
Always hardcore!
 
Регистрация: 04.03.2009
Адрес: СПб
Сообщения: 3,239
Версия Delphi: GCC/FPC/FASM
Репутация: 62149
По умолчанию

У вашего подхода есть один фатальный недостаток...
Код:
TMyThread.Create(...);
Create переопределён так, чтобы поток запускался сам.
Ссылок на него нету.
Вы разрушите объект?
__________________
Оставайтесь хорошими людьми...
VK id2634397, ds [at] phoenix [dot] dj
Ответить с цитированием
  #40  
Старый 01.04.2014, 11:11
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Прямые указатели зачастую позволяют значительно повысить скорость обработки. Например, можно иметь буферы, по которым бегают несколько указателей, и все эти указатели объединены в структуру. Или обход массива через указатели. Или из одних и тех же объектов в памяти строятся разные не владеющие ими структуры (дерево и массив, к примеру).
Многие из подобных вещей после запрета указателей, конечно, остаются реализуемыми, но с большими проблемами и теряют всю суть. А если указатели не запретить, то и собирать мусор каким-либо образом становится почти невозможно - ведь я запросто могу поставить указатель не на начало объекта (напр. на середину массива или на какое-то поле объекта), и сохранить его в какой-нибудь структуре. И будет совершенно непонятно, надо удалять объект или нет.
Что же касается "за памятью должен следить компьютер, а не программист" - видел как-то программу на .NET, которая после часа работы написала "Not Enough Memory" и отрубилась. Также сталкивался с тем, что всеми любимый SharpZipLib течет на некоторых архивах (у меня он обрабатывал круглые сутки десятки тысяч штук). То есть кривые руки и отсутствие мозгов даже на таком ограниченном языке, как C#, могут добиться утечек. А при прямых руках - мне бы и в голову не пришло уменьшать длину массива, не удаляя объекты, если я знаю, что это массив объектов. Поэтому я предпочитаю в любых мало-мальски критичных вещах следить за памятью самостоятельно. В большинстве случаев это не так трудно.
Цитата:
было предложено заменить это эрзацем управляемого кода
Вообще-то управляемый код очень близок к концепции ООП, чрезмерное использование которой я недолюбливаю. Ведь там по сути даже местный ассемблер (байткод) "аппаратно" поддерживает объекты. Абстракция от всего и вся, только и делай, что клепай объекты да делай их связи. Не надо думать о компьютере, о памяти, о ресурсах и скорости. Просто клепай абстракции. Все остальное сделает стометровая либа "под капотом". К чему это приводит, можно посмотреть: безумное количество быдлокода, который на C/Delphi просто не мог бы запуститься, тормоза и другие веселости. Тотальное абстрагирование располагает к этому.
А еще их легко ломать...
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 01.04.2014 в 11:38.
Ответить с цитированием
  #41  
Старый 01.04.2014, 16:43
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Bargest
Вообще-то управляемый код очень близок к концепции ООП
Вот на это можно пруфлинк?
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #42  
Старый 01.04.2014, 21:12
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Концепции ООП:
1) Всё - объект. Объект - экземпляр класса. Объект - абстракция.
2) Классы могут выстраивать структуру (как минимум дерево).
3) Объекты могут взаимодействовать друг с другом.
Ну или из любого учебника - "полиморфизм, инкапсуляция, наследование".

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

Все это сделано на уровне байт-кода в жабе/c#. Пруфлинк - почитать Instruction Set на документации oracle или доки на IL (с такими не сталкивался, реверсил C# "на ходу").
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 01.04.2014 в 21:28.
Ответить с цитированием
  #43  
Старый 01.04.2014, 23:06
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от PhoeniX
Create переопределён так, чтобы поток запускался сам.
Ссылок на него нету.
Вы разрушите объект?
У тебя неверное представление о достижимости. В языках со сборкой мусора фактическим владельцем всех ссылок выступает сборщик мусора, а код просто ходит под себя, не задумываясь о последствиях. Моя трактовка достижимости -- более общее понятие, распространяется и на переменные в стеке.

Где будут описаны твои переменные со ссылкой на создаваемый поток? Локальная переменная в процедуре точки входа будет считаться владеющей ссылкой и будет существовать всё время в пределах своей области видимости -- всё время, пока выполняется begin..end программы.

Цитата:
Сообщение от Bargest
В концепции ООП нет места таким понятиям, как "низкое быстродействие" или "конечная память". Все решается на сферических сущностях в вакууме (хотя из-за того, что это работает на реальном железе, порой приходится-таки учитывать расход ресурсов).
А где "низкое быстродействие" и "конечная память" в структурной теореме, например? В реляционной теореме? Абстракция -- на то и абстракция, чтобы описывать абстрактные вещи. Разница лишь в том, что структурный и реляционный подходы были реализованы в рамках научной школы, а байт-коды -- как бизнес-проект.

Цитата:
Сообщение от Bargest
Пруфлинк - почитать Instruction Set на документации oracle или доки на IL (с такими не сталкивался, реверсил C# "на ходу").
Стековая машина как стековая машина. Где там в байт-коде наследование, например?
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #44  
Старый 01.04.2014, 23:21
Аватар для Bargest
Bargest Bargest вне форума
Профессионал
 
Регистрация: 19.10.2010
Адрес: Москва
Сообщения: 2,390
Версия Delphi: XE3/VS12/FASM
Репутация: 14665
По умолчанию

Цитата:
Стековая машина как стековая машина. Где там в байт-коде наследование, например?
Класс (т.е. файл .class для джавы) описывается как наследник другого класса, поэтому всегда создается дерево классов. Далее на примере далвик, т.к. его помню почти наизусть, в жабе все аналогично.
new-instance создает непосредственно объект. Далее есть instance-of, проверяющий, является ли объект экземпляром класса или его наследником. Во все invoke-и и getfield/putfield передается строка с именем класса или же экземпляр класса, от которого в случае несущестовования метода/поля будет браться родитель и искаться соответствующий метод/поле. Ну и интерфейсы еще прилеплены. Таким образом, на уровне архитектуры машины может быть построено дерево классов и происходить работа с ним.
Полноценная реализация наследования (статического, разумеется).
Цитата:
А где "низкое быстродействие" и "конечная память" в структурной теореме, например?
Структурная теорема не призывает создавать абстракции от абстракций, притянутые за уши к понятию объекта. Фактически структурное программирование требует строить четкий алгоритм из относительно независимых блоков. Просто метод создания кода в том виде, в каком его удобно проектировать и поддерживать. Он не накладывает никаких ограничений на сам алгоритм, кроме того, что это не должно быть спагетти. Поэтому и работа со всеми ресурсами компьютера на нем легка.
ООП же требует, чтобы весь алгоритм был взаимодействием объектов, что вообще-то идет поперек принципа работы машины - последовательного выполнения действий. Понятно, что взаимодействие объектов можно описать последовательностью действий, но это уже выход за рамки ООП и переход к реализации, так сказать, "движка ООП".
__________________
jmp $ ; Happy End!
The Cake Is A Lie.

Последний раз редактировалось Bargest, 01.04.2014 в 23:49.
Ответить с цитированием
  #45  
Старый 03.04.2014, 08:37
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 577
Версия Delphi: 6
Репутация: выкл
По умолчанию

Цитата:
Сообщение от Bargest
new-instance создает непосредственно объект. Далее есть instance-of, проверяющий, является ли объект экземпляром класса или его наследником. Во все invoke-и и getfield/putfield передается строка с именем класса или же экземпляр класса, от которого в случае несущестовования метода/поля будет браться родитель и искаться соответствующий метод/поле.
Дискуссия внезапно оказалась плодотворной для меня. Всё это время пытался найти там подвох, чтобы было чем троллить, но тролль из меня хреновый. Зато ближе познакомился с байт-кодом JVM. Ты в очередной раз на меня положительно влияешь.

У меня уже сложилась в голове структура байт-кода Кантора, и теперь я могу сравнивать ее с другими реализациями. Шутки шутками, но мой байт-код больше всего похож на Бейсик 80-х.

Стало также понятно, почему так быстро удалось создать свой байт-код разработчикам "Фантома": они наверняка слегка изменили правила наследования и поиска методов, а всё остальное оставили как в Java. Это мои предположения, лезть в "Фантом" больше не хочется.

Цитата:
Сообщение от Bargest
Структурная теорема не призывает создавать абстракции от абстракций, притянутые за уши к понятию объекта. Фактически структурное программирование требует строить четкий алгоритм из относительно независимых блоков.
Вот это и есть разница между научным и бизнес-подходом. Структурное программирование было продумано от начала до конца и вписано в компиляторы заподлицо, а goto остался на нижнем уровне. И то, это не всем понравилось, нашлись и ретрограды, писавшие байки вроде "Настоящие мужчины используют Фортран". Они не верили структурным компиляторам.

В случае же ООП полной замены не произошло. ОО-средства были добавлены (прикручены сбоку -- в моей трактовке) в структурные языки, и классы с объектами стали сосуществовать рядом с обычными, необъектными типами. ОО в виде расширений было массовым, и со временем закрепилось в сознании именно в таком виде. Мол, объект -- это "запись с методами", доступная или напрямую, или по указателю. Стали накручивать на это другие слои, вроде интерфейсов, фабрик классов, и пошло-поехало.

На самом же деле, если почитать классические труды по ООП (того же Алана Кея), в них нигде не говорится, что объект -- это именно запись с методами. Даже посылку сообщения можно трактовать как прямой вызов метода, если требуется статическая типизация.

Вот я и поставил перед собой задачу вписать ООП в компилятор заподлицо, чтобы программистам было понятно, что настоящие мужчины используют записи с методами вот он -- новый уровень. Посмотрим, короче. Пока лишь вижу, что разработка у меня получается самобытной сама по себе, мне не нужно что-то специально придумывать, чтобы было как у всех, но свое. Ни на что не похоже получается просто так.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 15:34.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter