powered by simpleCommunicator - 2.0.37     © 2025 Programmizd 02
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Несколько вопросов по TDictionary
26 сообщений из 26, показаны все 2 страниц
Несколько вопросов по TDictionary
    #40097222
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго дня,
мучают сомнения.
1. приведёт ли уничтожение обьекта после помещения его в коллекцию TDictionary к уничтожению его и в коллекции TDictionary?
2. Надо ли проходить TDictionary и уничтожать добавленные в него обьекты перед уничтожением TDictionary?
3. Если через AddOrSetValue заменяю значение в коллекции удаляет ли TDictionary старый помещённый в это место обьект?

другими словами TDictionary хранит ссылки или клонирует помещённые в него обьекты?

если глянуть в исходники выглядит как хранение ссылки:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure TDictionary<TKey,TValue>.DoAdd(HashCode, Index: Integer; const Key: TKey; const Value: TValue);
var
  P: PItem;
begin
  P := @FItems[Index];
  P^.HashCode := HashCode;
  P^.Key := Key;
  P^.Value := Value;
  Inc(FCount);

  KeyNotify(Key, cnAdded);
  ValueNotify(Value, cnAdded);
end;


но в найденных примерах работы нигде не вижу удаления обьектов в коллекции перед удалением самой коллекции.
Если обьекты не удаляю то
ReportMemoryLeaksOnShutdown := True;
утечек не показывает. Но как то сомнительно это всё.

Спасибо
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097223
asviridenkov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hlopotun,

см doOwnKeys, doOwnValues
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097228
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hlopotun
другими словами TDictionary хранит ссылки или клонирует помещённые в него обьекты?

В Delphi нет универсальной операции клонирования.
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097233
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
hlopotun
другими словами TDictionary хранит ссылки или клонирует помещённые в него обьекты?

В Delphi нет универсальной операции клонирования.

если ссылки то как он тогда поступает с обьектом при замене значения коллекции? Удаляет его или нет?

doOwnKeys, doOwnValues это я так понимаю больше про TObjectDictionary, шас почитаю про него.
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097242
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
тут вылазит другая засада:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
var Key : string;
     lIPz: TMyObject:
..............
FIPs := TObjectDictionary<String, TIPZugang>.Create([doOwnsValues]);
.............
lIPz := TMyObject.Create;
lIPz.Id := nN;
lIPz.Time := Now;
FIPs.AddOrSetValue(Key, lIPz);
..............
for Key in FIPs.Keys do begin
     if ..........
        FIPs.Remove(Key); // Тут при попытке удаления из очереди вываливается C000005, в TDictionary тут этого не происходило
     end;
end;
...................
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097248
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
заменил на ExtractPair ошибка ушла, но всеравно непонятно почему она возникала
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097250
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hlopotun,

зато теперь вываливается C0000005 в конце:
Код: pascal
1.
2.
3.
............
............
FIPs.Free;



где бы хороший пример увидеть ...
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097251
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
а если убираю FIPs.Free в конце ошибки нет и утечек тоже не показывает.
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097255
Фотография peter64
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097260
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hlopotun// Тут при попытке удаления из очереди вываливается C000005

Дай угадаю: где-то между точек спрятался вызов lIPz.Free?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097261
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dimitry Sibiryakov

hlopotun// Тут при попытке удаления из очереди вываливается C000005

Дай угадаю: где-то между точек спрятался вызов lIPz.Free?..

нет,
вставил перед удалением коллекции
FIPs.Clear;
а уже потом
FIPs.Free;
и ошибка ушла.
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097268
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hlopotunвставил перед удалением коллекции
FIPs.Clear;
а уже потом
FIPs.Free;
и ошибка ушла.
А ещё через пять лет, когда этой пляски с бубном станет недостаточно и
говнокод опять упадёт, ты снова будешь на этом форуме говорить "ну это же пять
лет работало, значит ошибки нет". В морг.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097289
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hlopotun
тут вылазит другая засада:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
..............
for Key in FIPs.Keys do begin
     if ..........
        FIPs.Remove(Key); // Тут при попытке удаления из очереди вываливается C000005, в TDictionary тут этого не происходило
     end;
end;
...................



После FIPs.Remove нужно сразу Break делать. Иначе спилишь сук, на котором сидишь.
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097298
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DmSer,

да, спасибо. там рекурсия после удаления и break. Тут упрощённый вариант.
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097301
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hlopotun,

хотя рекурсия тут пожалуй тоже идея не очень. Редкий случай когда GOTO пригодится.
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097308
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hlopotun
мучают сомнения.
TDictionary не уничтожает ничего. Может уничтожать TObjectDctionary если его об этом попросить
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097310
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
for Key in FIPs.Keys.ToArray do begin

и никаких рекурсий и GOTO
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097331
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
for Key in FIPs.Keys do begin
     if ..........
        FIPs.Remove(Key); // Тут при попытке удаления из очереди вываливается C000005, в TDictionary тут этого не происходило
     end;
end;



Так нельзя писать... Keys это не собственный массив, это указатель на перечислитель.
Вы когда вызываете Remove, у вас массив ключей уменьшается, а перечислитель тот же и в какой-то момент у вас индекс превышает кол-во элементов, либо указывает не на тот элемент, потому что вы же удаляете из массива элементы.
Чтобы так можно писать надо как указали выше
Код: pascal
1.
2.
3.
4.
5.
for Key in FIPs.Keys.ToArray() do begin
     if ..........
        FIPs.Remove(Key); // Тут при попытке удаления из очереди вываливается C000005, в TDictionary тут этого не происходило
     end;
end;


Нужно сделать копию массива ключей и перебирать его, удаляя значения из словаря.
А ошибки в TDictionary не происходило потому что везло, вы же память не освобождали объектов.
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097494
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
всем спасибо,

получается примерно так, проход в обратном порядке и удаление по условию
Код: pascal
1.
2.
3.
for lnI := FIPs.Count - 1 downto 0 do
  if (FIPs.Items[FIPs.Keys.ToArray[lnI ]].Id = XY then
    FIPs.Remove(FIPs.Keys.ToArray[lnI]);
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097495
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hlopotun,

Песец у тебя тормоза на больших словарях будут.

TDictionary не приспособлен для доступа по номеру.

Это только в моем THashTable есть. :)
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097498
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
rgreat,

тогда так получается:

Код: pascal
1.
2.
3.
4.
5.
for Key in FIPs.Keys.ToArray() do begin
     if (FIPs.Items[Key].Id = XY then
        FIPs.Remove(Key);
     end;
end;




спасибо за замечания
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097502
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
2.
3.
for Key in FIPs.Keys.ToArray() do
     if (FIPs.Items[Key].Id = XY then
        FIPs.Remove(Key);


(Лишниe Begin End)
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097510
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hlopotun
Код: pascal
1.
2.
3.
4.
5.
for Key in FIPs.Keys.ToArray() do begin
     if (FIPs.Items[Key].Id = XY then
        FIPs.Remove(Key);
     end;
end;

Тогда уже так
Код: pascal
1.
2.
3.
4.
for Pair in FIPs.Pirs.ToArray do begin
  if (Pair.Value.Id = XY then
    FIPs.Remove(Pair.Key);
end;
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097511
hlopotun
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
_Vasilisk_

Тогда уже так
Код: pascal
1.
2.
3.
4.
for Pair in FIPs.Pirs.ToArray do begin
  if (Pair.Value.Id = XY then
    FIPs.Remove(Pair.Key);
end;



FIPs.Pirs.ToArray наверное FIPs.Keys.ToArray ?

Pairs по логике но его в TDictionary нет вроде. Может Items ? но его в ToArray не запихнуть
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097522
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пройтись по ключам, собрать в список нужные. Потом пройтись по списку нужных и удалить из словаря значения. Если удалять немногие из большого списка то выйдет существенная экономия в памяти да и в скорости в сравнении с ToArray
...
Рейтинг: 0 / 0
Несколько вопросов по TDictionary
    #40097535
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hlopotun
Pairs по логике но его в TDictionary нет вроде. Может Items ? но его в ToArray не запихнуть
Ошибся. Вот так правильно
Код: pascal
1.
2.
3.
4.
for Pair in FIPs.ToArray do begin
  if Pair.Value.Id = XY then
    FIPs.Remove(Pair.Key);
end;
...
Рейтинг: 0 / 0
26 сообщений из 26, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Несколько вопросов по TDictionary
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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