Флейм
GameDev.ru / Флейм / Форум / снова TList<TArray>

снова TList<TArray>

Страницы: 1 2 Следующая »
MiraПостоялецwww7 дек. 201815:18#0
опять встал на грабли с этим типом данных.
писал мультитредную функцию но поймал ошибку. написал тестовый пример - ошибка на нем повторяется (что исключает мои ошибки с повреждением памяти например)
значит ошибка в самом подходе, ну либо ваще баг конпеллятора.
что я тут неверно сделяль?

есть такой код

procedure TForm1.BitBtn1Click(Sender: TObject);
var
 list:TList<TArray<integer>>;
 n,i:integer;
 temp : TArray<integer>;
 tempresults:TArray<TArray<integer>>;
begin
 list:=TList<TArray<integer>>.Create;

 for n:=0 to 31 do begin
  temp:=nil;
  setlength(temp,1024);
  for i:=0 to high(temp) do temp[i]:= n * 10000 + i; //инициализируем массив всяким дерьмом и кладем его в List
  list.Add(temp);
 end;

 setlength(tempresults,list.Count); //тут мы будем сохранять результат вычислений
 TParallel.&For(0,list.Count-1,procedure(listindex: integer)
 var
  idx:integer;
  temparray:TArray<integer>;
 begin
  temparray:=nil; указываем явно что будем использовать потом другой экземпляр
  setlength(temparray,2048);
  for idx:=0 to high(list[listindex]) do temparray[idx]:=list[listindex][idx] + 100; //заполняем новый массив частично, используя при этом старый
  tempresults[listindex]:= temparray; //сохраняем полученный результат во временном наборе
 end);

 for n:=0 to list.Count-1 do
    list[n]:=tempresults[n]; //тут ловим исключение RTL что то там с освобождением массива и декрементом счетчика жизни.
 if length(list[0])=0 then sleep(0); // совершаем какоето бессмысленное действие чтоб оптимизатор не слил ничего раньше времени
end;

при этом, если для сохранения не использовать промежуточный массив, а сразу скажем совать в list то ошибка не возникает

Правка: 7 дек. 2018 15:24

MiraПостоялецwww7 дек. 201815:26#1
у кого есть возможность откомпильте плиз код)
требуется включение модулей Threading, SyncObjs ну и генерики понятно
CDПостоялецwww7 дек. 201815:27#2
Mira
В 10.2 update 3 не воспроизводится.
MiraПостоялецwww7 дек. 201815:32#3
Мдааа проверил в 10.3 тоже нет. видимо в Berlin какой то внутренний баг((( а может и ранее. так то я не готов переходить на 10.3 там полюбасу добавили новых багов, да и есть пара несовместимостей
баг скорее всего именно в генериках, так как я уже писал, что ловил неприятности с этим листом массивов и без потоков.

Правка: 7 дек. 2018 15:38

=A=L=X=Постоялецwww7 дек. 201815:38#4
есть вероятность, что ошибка не в этом коде, а что какой то другой код чуточку ломает кучу или стек и это вызывает совершенно непонятные и ничем не обоснованные внешне глюки где угодно.
именно зависимость от компилятора, опций компиляции и других фаз луны является весомым признаком такого положения вещей.
MiraПостоялецwww7 дек. 201815:42#5
=A=L=X=
неа
я поэтому и написал чистый тестовый код.
проверил на свежесозданном проекте - Berlin тут спотыкается 10.3 нет, и 10.2 тоже написали что нет.
MiraПостоялецwww7 дек. 201815:44#6
че теперь делать) насильно переходить на старшую версию, или изменить код чтоб не было такой операции но ждать теперь подвоха в другом месте  из за этого бага  ><
=A=L=X=Постоялецwww7 дек. 201815:45#7
Mira

Приведи еще точное сообщение об ошибке, это может прояснить можно ли с этим бороться и как банальным поиском.

MiraПостоялецwww7 дек. 201815:48#8
=A=L=X=
вот тут возникает AV при
list[n]:=tempresults[n];
+ Показать
=A=L=X=Постоялецwww7 дек. 201815:53#9
Угу, есть такая трабла: https://stackoverflow.com/questions/41047688/how-to-work-around-d… dynamicarrays
What happen is, the wrong TypeInfo is passed to DynArrayClear. In the case of a TList<TStringDynArray>, TypeInfo(TArray<TStringDynArray>) is passed instead of TypeInfo(TStringDynArray).

Опечатка в кишках исходного кода TList<>.
MiraПостоялецwww7 дек. 201816:19#10
и как это обойти? VCL и RTL на сколько я помню просто так не перекомпиллировать, там есть какие то сложности. как то подобную ошибку в их движке БД я фиксил кидая изменненый юнит в папку проекта, но это очень нехороший способ. при смене версии потом это вылезет неприятностями

изменение самого юнита ничего не даст, при сборке используется прекомпиллированный dcu, а там файл содержит некоторые специфичные данные и его заменить не возможно.

Правка: 7 дек. 2018 16:22

CDПостоялецwww7 дек. 201816:43#11
Mira
10.2u3 неплох, можно и перейти
субъективно заметно поменьше глюков

10.3 пока фигня, переходить не стоит

Mira
> и как это обойти?
Через rtti получить адрес функции, снять защиту через VirtualProtect и прописать jmp на корректную реализацию. Все это обложить {$IFDEF VER310} {$ENDIF}

Правка: 7 дек. 2018 16:57

MrShoorУчастникwww7 дек. 201820:05#12
Mira
> и как это обойти?
Заведи TMyList в юните MyGenerics.Collections в который скопипасть все из стандартного TList. Исправь там. Везде используй TMyList. Когда будешь готов отказаться от копипасты, то просто в MyGenerics.Collections тип объявишь через алиас: TMyList<T> = TList<T>.
MiraПостоялецwww7 дек. 201821:17#13
балин). не одной сборки еще не видел без критичных багов
а апдейты с фиксами вроде как по подписке только
MiraПостоялецwww7 дек. 201821:26#14
пока что заменю на свой тип IAlignedBuffer чтоб модули с затычками не плодить
только  части кода у меня используется с массивом if length(array)<0 then setlength(array,0) могут вылезти гдето проблемы

жалко что такой код не работает

function TAlignedBuffer<T>.GetLength: integer;
begin
  if self=nil then exit(-1);
  result:=FLength;
end;

Правка: 7 дек. 2018 21:26

Страницы: 1 2 Следующая »

/ Форум / Флейм / Программирование

2001—2018 © GameDev.ru — Разработка игр