powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
25 сообщений из 135, страница 2 из 6
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892502
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
если у меня в потоке создаются огромные массивы - они остаются, занимая память
Нет
Андрей Игоревич
в компиляторе их можно прощелкать на всю глубину и посмотреть на нули
Вы видите случайный мусор того, что осталось по старым указателям
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892528
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

чтобы не ловить AV при освобождении несуществующего объекта, попробуй
Код: pascal
1.
2.
3.
4.
procedure TForm1.Button5Click(Sender: TObject);
begin
   if Assigned(MyThread) then FreeAndNil(MyThread);
end;
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892537
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
Андрей Игоревич,

чтобы не ловить AV при освобождении несуществующего объекта, попробуй
Код: pascal
1.
2.
3.
4.
procedure TForm1.Button5Click(Sender: TObject);
begin
   if Assigned(MyThread) then FreeAndNil(MyThread);
end;


Это и так делается внутри FreeAndNil, не учи человека плохому
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892539
Dimitry Sibiryakov

Андрей ИгоревичПо факту - Thread.Free не делает поток Nil

Естественно не делает. Не забота объекта следить сколько у тебя указателей на него. Ты их
можешь присвоить хоть миллион, хоть миллиард. Сам наплодил - самому и очищать.

Это азы работы с указателями.

Но почему для остальных классов деструктор очищает указатели, а для потоков - нет? И почему тогда штатный Free этого не учитывает (например как предложил Док) и после завершения потока вылетает с ошибкой доступа к памяти.

_Vasilisk_
Андрей Игоревич
если у меня в потоке создаются огромные массивы - они остаются, занимая память
Нет
Андрей Игоревич
в компиляторе их можно прощелкать на всю глубину и посмотреть на нули
Вы видите случайный мусор того, что осталось по старым указателям

Надо потестировать, у других классов ведь полностью очищаются. А если у меня будет миллиард указателей в потоке (ну вдруг я так программирую) - они таки будут сжирать гигабайт памяти?

Док
Андрей Игоревич,

чтобы не ловить AV при освобождении несуществующего объекта, попробуй
Код: pascal
1.
2.
3.
4.
procedure TForm1.Button5Click(Sender: TObject);
begin
   if Assigned(MyThread) then FreeAndNil(MyThread);
end;


Спасибо, очень пригодиться.

А вот есть вопрос из другой оперы (из-за которого я опять вернулся к этому :) )
Вот запускаю я множество потоков, по результатам у меня происходит событие (ну так я сделал) в основном потоке, как сделать так что бы срабатывало только событие последнего выполняемого потока, считать потоки? При том я не знаю сколько у меня потоков и какой именно будет последним. Считать потоки в событии?
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892540
Василий 2
Док
Андрей Игоревич,

чтобы не ловить AV при освобождении несуществующего объекта, попробуй
Код: pascal
1.
2.
3.
4.
procedure TForm1.Button5Click(Sender: TObject);
begin
   if Assigned(MyThread) then FreeAndNil(MyThread);
end;


Это и так делается внутри FreeAndNil, не учи человека плохому

Если FreeOnTerminate:=true то FreeAndNil вылетит с ошибкой доступа к памяти.
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892552
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
Если FreeOnTerminate:=true то FreeAndNil вылетит с ошибкой доступа к памяти.
FreeOnTerminate:=true это совсем другой расклад
довольно низкоуровневый примитив что бы свободно применять его в юзер-коде
для этого нужно очень веское основание
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892560
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
Dimitry Sibiryakov

пропущено...

Естественно не делает. Не забота объекта следить сколько у тебя указателей на него. Ты их
можешь присвоить хоть миллион, хоть миллиард. Сам наплодил - самому и очищать.

Это азы работы с указателями.

Но почему для остальных классов деструктор очищает указатели, а для потоков - нет? И почему тогда штатный Free этого не учитывает (например как предложил Док) и после завершения потока вылетает с ошибкой доступа к памяти.

_Vasilisk_
пропущено...
Нет
пропущено...
Вы видите случайный мусор того, что осталось по старым указателям

Надо потестировать, у других классов ведь полностью очищаются. А если у меня будет миллиард указателей в потоке (ну вдруг я так программирую) - они таки будут сжирать гигабайт памяти?
Никто ничего сам, если это не заложено не чистит
Dimitry Sibiryakov и _Vasilisk_ вам правильно написали, надо расти над собой
сам навыделал, сам и чисти, мы же про системный язык, а не про яву рассуждаем???
хотя есть решения и для ленивых 11957089
Андрей Игоревич

Док
Андрей Игоревич,

чтобы не ловить AV при освобождении несуществующего объекта, попробуй
Код: pascal
1.
2.
3.
4.
procedure TForm1.Button5Click(Sender: TObject);
begin
   if Assigned(MyThread) then FreeAndNil(MyThread);
end;


Спасибо, очень пригодиться.

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

не пользуйтесь FreeOnTerminate:=true и всё будет более-менее в порядке

хотя с тем, что архитектура TThread вызывает много вопросов я очень даже согласен, но что есть то есть
бага записанная в кучу копий, становится фичей
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892564
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
А если у меня будет миллиард указателей в потоке (ну вдруг я так программирую) - они таки будут сжирать гигабайт памяти?
Как вы эти указатели получаете? На каждый New/GetMem/Create должен следовать Dispose/FreeMem/Free. Вызов SetLength() никакой финализации не требует.

При выполнении этих правил никакая память утекать не будет.

Док
чтобы не ловить AV при освобождении несуществующего объекта, попробуй
Код: pascal
1.
2.
3.
4.
procedure TForm1.Button5Click(Sender: TObject);
begin
   if Assigned(MyThread) then FreeAndNil(MyThread);
end;

Док, советуешь феерическую хрень.
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892565
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
FreeOnTerminate:=true это совсем другой расклад
довольно низкоуровневый примитив что бы свободно применять его в юзер-коде
для этого нужно очень веское основание
Да ладно. Одно правило нужно выполнять - сохраняем ли мы ссылку на объект или нет
Код: pascal
1.
2.
3.
4.
begin
  FThread := TMyThread1.Create;  // в 95% FreeOnTerminate должно быть False
  TMyThread2.Create;  // в 100% FreeOnTerminate должно быть True
end;
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892566
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичНо почему для остальных классов деструктор очищает указатели

Что-то ты путаешь. Ни для каких классов освобождение памяти не изменяет значение указателя.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892567
kealon(Ruslan)

ну вот "посмотреть что делает этот метод" не судьба? или работать надо?

А как правильно проверять существование потока?
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892569
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
А как правильно проверять существование потока?
Потока или экземпляра объекта TThread?
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892572
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ИгоревичА как правильно проверять существование потока?

Правильно - никак. Потоки это оружие класс FaF. Ты его запускаешь, а дальше оно уже само.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892590
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич
kealon(Ruslan)

ну вот "посмотреть что делает этот метод" не судьба? или работать надо?

А как правильно проверять существование потока?

1. Если указатель на поток не сохраняется ("TMyThread2.Create;"), то никак.
2. Если указатель на поток сохраняется ("th := TMyThread2.Create;"), то обязательно самому FreeAndNil-ить поток и соответственно "существует" == "th <> nil". FreeOnTerminate - только для п.1
3. Если хочется проверить, завершился ли поток, то есть например ReturnValue, но его все равно надо будет выставить в Execute самому
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892594
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2
3. Если хочется проверить, завершился ли поток, то есть например
.Finished, который поток выставляет сам.
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892599
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНо почему для остальных классов деструктор очищает указатели,
Никакой класс не очищает указатель и TThread как представитель классов этого конечно же не делает.
Надежно чистить указатель на TThread можно в OnTerminate потока, вне зависимости от флага FreeOnTerminate.
Другое дело что проверка указателя на nil с включенным флагом FreeOnTerminate мало что гарантирует:
1. Делаем проверку на nil. Поток еще живой
2. Поток надумал закончится, зашел в OnTerminate, обнулил ссылку на себя
3. Обращаемся к потоку получаем AV.
Из плюсов то, что OnTerminate выполняется синхронно с основным потоком. Поэтому могут существовать кейсы когда это будет работать.
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892618
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
kealon(Ruslan)
FreeOnTerminate:=true это совсем другой расклад
довольно низкоуровневый примитив что бы свободно применять его в юзер-коде
для этого нужно очень веское основание
Да ладно. Одно правило нужно выполнять - сохраняем ли мы ссылку на объект или нет
Код: pascal
1.
2.
3.
4.
begin
  FThread := TMyThread1.Create;  // в 95% FreeOnTerminate должно быть False
  TMyThread2.Create;  // в 100% FreeOnTerminate должно быть True
end;


makhaon
авторНо почему для остальных классов деструктор очищает указатели,

Никакой класс не очищает указатель и TThread как представитель классов этого конечно же не делает.
Надежно чистить указатель на TThread можно в OnTerminate потока, вне зависимости от флага FreeOnTerminate.
Другое дело что проверка указателя на nil с включенным флагом FreeOnTerminate мало что гарантирует:
1. Делаем проверку на nil. Поток еще живой
2. Поток надумал закончится, зашел в OnTerminate, обнулил ссылку на себя
3. Обращаемся к потоку получаем AV.
Из плюсов то, что OnTerminate выполняется синхронно с основным потоком. Поэтому могут существовать кейсы когда это будет работать.

налопшичить кучу кода, и всё ради "высвободить хэндл как поток завершится", ну и нафига?
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892622
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Док, советуешь феерическую хрень.

че хрень-то сразу? :)

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

kealon(Ruslan)
не пользуйтесь FreeOnTerminate:=true и всё будет более-менее в порядке

им нужно пользоваться, только надо знать где и как :)

Я для себя определил так:
- если экземпляр потока объявлен в локальной переменной, то FreeOnTerminate:=true, ибо после выхода из процедуры видимость переменной все равно потеряется и nil-ить ее специально нет никакой необходимости.
- во всех остальных случаях FreeOnTerminate:= false и FreeAndNil.
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892624
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
че хрень-то сразу? :)

В Лазаре, промежду прочим, если не подставлять эту прокладку, в некоторых случаях получаешь ошибку еще на этапе компиляции. Я сейчас точно ситуацию не воспроизведу кодом (лень, если честно). Но когда я плотно изучал работу потоков, частенько с этим сталкивался.
При чем тут Лазарь-не Лазарь, потоки...
Внутри FreeAndNil и так вызывается проверка на Assigned, как и в Free.
Вот, че.
Уже ж проходили много раз.
А если в указателе (в "переменной объекта") мусор, то эта проверка - абсолютно бесполезна к тому же.


Док
- если экземпляр потока объявлен в локальной переменной, то FreeOnTerminate:=true
Это странный критерий.
Если ждать результатов выполнения потока не нужно, если не нужно управлять потоком - то можно можно использовать FreeOnTerminate, я бы сказал так.
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892657
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
Если ждать результатов выполнения потока не нужно, если не нужно управлять потоком - то можно можно использовать FreeOnTerminate, я бы сказал так.
Но таких ситуаций ничтожно мало. Кроме того, при выходе из программы стопорнуть поток как правило всё равно надо, и тут начинаются проблемы.
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892660
Фотография Док
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock
При чем тут Лазарь-не Лазарь, потоки...
Внутри FreeAndNil и так вызывается проверка на Assigned, как и в Free.

В лазаре так (fpc3.0.4: ..\source\rtl\objpas\sysutils\sysutils.inc)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
    procedure FreeAndNil(var obj);
      var
        temp: tobject;
      begin
        temp:=tobject(obj);
        pointer(obj):=nil;
        temp.free;
      end;  


Возможно в дельфях по-другому, давно в потроха не заглядывал

kealon(Ruslan)
при выходе из программы стопорнуть поток как правило всё равно надо

это ты о чем?
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892684
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док

В лазаре так (fpc3.0.4: ..\source\rtl\objpas\sysutils\sysutils.inc)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
    procedure FreeAndNil(var obj);
      var
        temp: tobject;
      begin
        temp:=tobject(obj);
        pointer(obj):=nil;
        temp.free;
      end;  


Возможно в дельфях по-другому, давно в потроха не заглядывал

Ты в потроха TObject.Free загляни и узнаешь великую тайну - чем он отличается от .Destroy :)
Док
kealon(Ruslan)
при выходе из программы стопорнуть поток как правило всё равно надо

это ты о чем?

Подозреваю он о том, что при завершении программы нельзя оставлять в памяти работающие потоки.
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892685
Фотография Kast2K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей Игоревич,

может так проще будет:

автор
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
var
  Form1: TForm1;
  MyThread:Thread;
implementation

{$R *.xfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  MyThread:=Thread.Create(True);
  MyThread.FreeOnTerminate:=True;
  MyThread.OnTerminate:=MyThreadStop;
  MyThread.Resume;
end;

procedure TForm1.MyThreadStop(Sender: TObject);
begin
  MyThread:=nil;
end;




А внутреннюю очистку как-то самостоятельно...
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892701
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)
YuRock
Если ждать результатов выполнения потока не нужно, если не нужно управлять потоком - то можно можно использовать FreeOnTerminate, я бы сказал так.
Но таких ситуаций ничтожно мало.
У меня бывали пару раз :)

kealon(Ruslan)
Кроме того, при выходе из программы стопорнуть поток как правило всё равно надо, и тут начинаются проблемы.
Насколько я помню, дельфя такие потоки в массив складывает и при закрытии сама удаляет. Впрочем, проблемы все равно возможны.
Если надо все же вручную закрывать - значит FreeOnTerminate не подходит.
...
Рейтинг: 0 / 0
Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
    #39892703
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Док
В лазаре так (fpc3.0.4: ..\source\rtl\objpas\sysutils\sysutils.inc)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
    procedure FreeAndNil(var obj);
      var
        temp: tobject;
      begin
        temp:=tobject(obj);
        pointer(obj):=nil;
        temp.free;
      end;  



Возможно в дельфях по-другому, давно в потроха не заглядывал
Это копипаст из делфи. Проверка на нил в Free.
...
Рейтинг: 0 / 0
25 сообщений из 135, страница 2 из 6
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Много малых вопросов о работе с памятью при работе с динамическими массивами и классами.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]