Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Исправление Ошибок в TList после Обновления до Delphi XE8

Delphi , Компоненты и Классы , Списки

В последних версиях Delphi, включая XE8, разработчики столкнулись с рядом проблем, связанных с использованием обобщенных коллекций. Одной из таких проблем является баг в реализации класса TList<T>, который приводит к некорректному поведению при работе с элементами списка. В данной статье мы рассмотрим, как этот баг проявляется, и предложим возможные пути его решения.

Проблема

Проблема заключается в том, что после обновления до версии Delphi XE8, некоторые проекты начинают выдавать неверные данные. Это может быть связано с изменением реализации класса TList<T>. Для демонстрации проблемы рассмотрим следующий пример кода:

program XE8Bug1;
{$APPTYPE CONSOLE}
uses
  System.SysUtils, Generics.Collections;
type
  TRecord = record
    A: Integer;
    B: Int64;
  end;
var
  FRecord: TRecord;
  FList: TList<TRecord>;
begin
  FList := TList<TRecord>.Create;
  FRecord.A := 1;
  FList.Insert(0, FRecord);
  FRecord.A := 3;
  FList.Insert(1, FRecord); // здесь должен быть индекс 1, но из-за бага он перезапишет элемент с индексом 0
  FRecord.A := 2;
  FList.Insert(1, FRecord);
  Writeln(IntToStr(FList[0].A) + IntToStr(FList[1].A) + IntToStr(FList[2].A)); // в XE8 выведет "120" вместо ожидаемого "123"
end.

Решение проблемы

Официальное решение от Embarcadero пришло с обновлением XE8 до версии 1, однако разработчикам, столкнувшимся с этой проблемой, не обязательно ждать обновления. Существует неофициальный фикс, который можно найти здесь. Кроме того, был предложен альтернативный путь решения - использование модулей System.Generics.Defaults.pas и System.Generics.Collections.pas из Delphi XE7 в проектах, что позволит избежать проявления бага.

Подробности бага

Проблема заключается в методе TListHelper.InternalInsertN, который зависит от размера данных. В коде метода обнаружены неточности в перемещении данных, что и приводит к ошибке при вставке элементов в список.

procedure TListHelper.InternalInsertN(AIndex: Integer; const Value);
var
  ElemSize: Integer;
begin
  // ... (проверка индекса)
  ElemSize := ElSize;
  if AIndex <> FCount then
    Move(PByte(FItems^)[AIndex * ElemSize], PByte(FItems^)[(AIndex * ElemSize) + 1], (FCount - AIndex) * ElemSize);
  // здесь должна быть ошибка в указании индекса для перемещения данных
  Move(Value, PByte(FItems^)[AIndex * ElemSize], ElemSize);
  // ... (дальнейший код)
end;

Рекомендации

Рассмотрите возможность использования неофициального фикса или возврата к использованию модулей из Delphi XE7. Однако, если вы решите восстанавливать реализацию XE7, убедитесь, что RTL, VCL и FMX также используют исправленные модули, чтобы избежать других проявлений этого дефекта.

Заключение

Разработчикам, работающим с обобщенными коллекциями в Delphi XE8, следует быть внимательными к этой проблеме и принять меры для её устранения. Использование неофициального фикса или возвращение к модулям из предыдущей версии может помочь восстановить корректную работу вашего проекта.

Создано по материалам из источника по ссылке.

Проблема заключается в ошибке в классе `TList` после обновления до Delphi XE8, которая приводит к неправильной вставке элементов в список из-за некорректного перемещения данных.


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Списки ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-09 08:14:16/0.005889892578125/0