Форум: "Основная";
Текущий архив: 2003.10.20;
Скачать: [xml.tar.bz2];
Вниз
Не могу понять происхождение глюка Найти похожие ветки
← →
Woolen (2003-10-08 14:51) [0]Помогите, пожалуйста. Совершенно непонятный глюк:
var
Form1: TForm1;
Arr1, Arr2, Arr3: array of Integer;
procedure TForm1.Button1Click(Sender: TObject);
var
Txt: string;
Cicle: Integer;
Lngth: Integer;
begin
SetLength(Arr1,100);
SetLength(Arr2,100);
SetLength(Arr3,100);
for Cicle := 0 to Length(Arr1) - 1 do
Arr1[Cicle] := Cicle + 1;
Arr2 := Arr1;
Lngth := Length(Arr1);
AddIntArrayMMX(Arr1,Arr2,Arr3,Lngth);
Txt := IntToStr(Arr3[Length(Arr3) - 1]);
ShowMessage(Txt);//НАЧИНАЕТ ЖЕСТОКО СЫПАТЬ ОШИБКАМИ...
end;
procedure AddIntArrayMMX(Arr1: array of Integer; Arr2: array of Integer; var
ResultArr: array of Integer; const ArrLen: Integer);
var
Count: Integer;
Remainder: Boolean;
begin
Count := ArrLen * 2;
Remainder := (ArrLen mod 2) > 0;
repeat
Dec(Count,2);
ResultArr[Count] := Arr1[Count] + Arr2[Count];
ResultArr[Count + 1] := Arr1[Count + 1] + Arr2[Count + 1];
until Count = 0;
if Remainder then
ResultArr[ArrLen - 1] := Arr1[ArrLen - 1] + Arr2[ArrLen - 1];
end;
Если, кто может, поскажите, что это могло бы быть?
← →
Skier (2003-10-08 14:59) [1]1)Ты в курсе что здесь
Arr2 := Arr1;
происходит копирование указателя,а не значений массива ?
2)А что лежит в Arr3[Length(Arr3) - 1]);
(хотя это не должно влиять...)
← →
han_malign (2003-10-08 15:18) [2]SetLength( Arr1, 100);
SetLength(Arr2, 100);
SetLength(Arr3, 100);
Lngth := Length( Arr1);
AddIntArrayMMX(Arr1,Arr2,Arr3, Lngth);
Count := ArrLen * 2;
ResultArr[ Count] := Arr1[ Count] + Arr2[ Count];
- аккуратнее надо быть
← →
han_malign (2003-10-08 15:25) [3]и лучше While, а не repeat, а то если изначально Count=0 - бяка будет...
З.Ы. я так понимаю, что нужно было просто выровнять по 2-ке:
Count := ArrLen;
Remainder := (ArrLen mod 2) > 0;
if(Remainder)then Dec(Count);
← →
Woolen (2003-10-08 15:46) [4]
> 1)Ты в курсе что здесь Arr2 := Arr1; происходит копирование
> указателя,а не значений массива ?
Да, в курсе. Все равно должно работать. И на малых массивах типа 10 элементов работает, а на 100 - уже нет.
> 2)А что лежит в Arr3[Length(Arr3) - 1]);
Я думаю, последний элемент массива Arr3 - то есть сумма последних элементов Arr1 и Arr2. Разве нет?
> аккуратнее надо быть
Постараюсь, только я не понял, где я напартачил, по моему у меня в коде то же самое, что и ты написал.
> и лучше While, а не repeat, а то если изначально Count=0
> - бяка будет
здесь repeat будет быстрее на входе в цикл, а если Count = 0, то процедуру вызывать не надо
← →
han_malign (2003-10-08 15:50) [5]> только я не понял, где я напартачил, по моему у меня в коде то же самое, что и ты написал
- вот именно "то же самое", а должно быть по другому - повнимательнее на выделенные лексему посмотри...
ArrLen=Lnght=Length(Arr1)=100
Count=ArrLen*2=200
Arr1[Count]==>Arr1[200]!!!
← →
Woolen (2003-10-08 16:12) [6]
> ArrLen=Lnght=Length(Arr1)=100
> Count=ArrLen*2=200
> Arr1[Count]==>Arr1[200]!!!
Спасибо! Я уже думал не найду!
← →
Woolen (2003-10-08 16:17) [7]Совсем тупой вопрос. А что, динамические массивы в стеке создаются?
SetLength(Arr1,2621440);
SetLength(Arr2,2621440);
SetLength(Arr3,2621440);
ничего необычного не вызывает, но потом в процедуре сложения возникакет EStackOverFlow.
← →
Verg (2003-10-08 16:26) [8]
> А что, динамические массивы в стеке создаются?
Нет не в стеке.
Просто, когда ты передаешь этот массив в процедуру в качестве параметра по значению, копилятор вынужен в начале процедуры вставить код, который скопирует весь массив в стек.
Для того, чтобы этого не происходило описывай такие параметры как const, если в процедуре не будешь менять элементы массива, или var если будешь.
← →
Verg (2003-10-08 16:32) [9]Да, кроме всего прочего, при передаче массивов позначению дико жрется время выполнения вызова такой процедуры (как раз на создание копии массива).
Так что,.... const или var
← →
Woolen (2003-10-08 16:44) [10]
> описывай такие параметры как const
а разве по дефолту передаваемый парамент не const?
← →
Woolen (2003-10-08 16:47) [11]2 Verg
спасибо, работает
← →
Verg (2003-10-08 16:54) [12]
> а разве по дефолту передаваемый парамент не const?
Нет.
С динамическими массивами тут вообще хитро все.
когда ты пишешь
procedure proc( A : array of integer);
begin
a[0]:=10;
end;
A - это "открытый массив", и происходит то, о чем я тебе писал
a[0]:=10 присвоит 10 нулевому элемнту копии массива в стеке.
А вот если бы
type
Tma = array of integer;
....
procedure proc(A : tma);
begin
a[0]:=10;
end;
вот здесь A - это динам. массив и всегда физически передается ссылка на массив, т.е. копирование на стек не происходит.
a[0]:=10 присвоит 10 реально нулевому элементу того массива, который был передан в процедуру.
← →
Woolen (2003-10-08 17:31) [13]Написал просто:
procedure AddIntArrayMMX(const Arr1: array of Integer; const Arr2: array of Integer; var ResultArr: array of Integer; const ArrLen: Integer);
Работает с любыми размерами вплоть до нехватки виртуальной памяти. Еще раз, спасибо.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.10.20;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.008 c