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

снова TList<TArray>

Страницы: 1 2 Следующая »
#0
(Правка: 15:24) 15:18, 7 дек. 2018

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

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

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 то ошибка не возникает


#1
15:26, 7 дек. 2018

у кого есть возможность откомпильте плиз код)
требуется включение модулей Threading, SyncObjs ну и генерики понятно

#2
15:27, 7 дек. 2018

Mira
В 10.2 update 3 не воспроизводится.

#3
(Правка: 15:38) 15:32, 7 дек. 2018

Мдааа проверил в 10.3 тоже нет. видимо в Berlin какой то внутренний баг((( а может и ранее. так то я не готов переходить на 10.3 там полюбасу добавили новых багов, да и есть пара несовместимостей
баг скорее всего именно в генериках, так как я уже писал, что ловил неприятности с этим листом массивов и без потоков.

#4
15:38, 7 дек. 2018

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

#5
15:42, 7 дек. 2018

=A=L=X=
неа
я поэтому и написал чистый тестовый код.
проверил на свежесозданном проекте - Berlin тут спотыкается 10.3 нет, и 10.2 тоже написали что нет.

#6
15:44, 7 дек. 2018

че теперь делать) насильно переходить на старшую версию, или изменить код чтоб не было такой операции но ждать теперь подвоха в другом месте  из за этого бага  ><

#7
15:45, 7 дек. 2018

Mira

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

#8
15:48, 7 дек. 2018

=A=L=X=
вот тут возникает AV при
list[n]:=tempresults[n];

+ Показать
#9
15:53, 7 дек. 2018

Угу, есть такая трабла: 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<>.

#10
(Правка: 16:22) 16:19, 7 дек. 2018

и как это обойти? VCL и RTL на сколько я помню просто так не перекомпиллировать, там есть какие то сложности. как то подобную ошибку в их движке БД я фиксил кидая изменненый юнит в папку проекта, но это очень нехороший способ. при смене версии потом это вылезет неприятностями

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

#11
(Правка: 16:57) 16:43, 7 дек. 2018

Mira
10.2u3 неплох, можно и перейти
субъективно заметно поменьше глюков

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

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

#12
20:05, 7 дек. 2018

Mira
> и как это обойти?
Заведи TMyList в юните MyGenerics.Collections в который скопипасть все из стандартного TList. Исправь там. Везде используй TMyList. Когда будешь готов отказаться от копипасты, то просто в MyGenerics.Collections тип объявишь через алиас: TMyList<T> = TList<T>.

#13
21:17, 7 дек. 2018

балин). не одной сборки еще не видел без критичных багов
а апдейты с фиксами вроде как по подписке только

#14
(Правка: 21:26) 21:26, 7 дек. 2018

пока что заменю на свой тип IAlignedBuffer чтоб модули с затычками не плодить
только  части кода у меня используется с массивом if length(array)<0 then setlength(array,0) могут вылезти гдето проблемы

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

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

Страницы: 1 2 Следующая »
ФлеймФорумПрограммирование