Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.10.20;
Скачать: CL | DM;

Вниз

Не могу понять происхождение глюка   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.018 c
14-65595
michael
2003-10-01 14:21
2003.10.20
Как читать книги по программированию?


14-65584
Думкин
2003-10-02 06:36
2003.10.20
С днем рождения! 2 октября.


1-65409
Deimos
2003-10-07 18:50
2003.10.20
Как изменить стиль заголовка окна, точнее цвет и форму кнопок


3-65393
Nick-From
2003-09-05 14:18
2003.10.20
Избежание переполнения таблиц


14-65599
Knight
2003-09-29 23:06
2003.10.20
Что не говорите, а в рекламе часто правду говорят...