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

Вниз

Корректное создание массива из пользовательских структур.   Найти похожие ветки 

 
justnick   (2006-05-03 19:53) [0]

Привет всем. У меня тут проблемка с массивом структур. Вот выдержки из кода:

type
TMyRecord = record
 var1, var2: Double;
 // и т.д. всего на 272 байта
end;

TForm1 = class(TForm)
public
 MRA: array of TMyRecord;
 IA: array of Integer;
 procedure MRACalc(var MR: TMyRecord);
end;

implementation
procedure TForm1.Button1Click(Sender: TObject);
begin
// создаю MRA, пробовал через setLength и GetMem
 SetLength(MRA, N);
// GetMem(MRA, SizeOf(TMyRecord) * N);

// создаю и инициализирую массив IA
 SetLength(IA, M);
 for i := 0 to M - 1 do IA[i] := i;
// на этом работа с IA в данной процедуре заканчивается

// далее идет довольно большой блок операций с MRA и вызовом проедуры MRACalc

end;

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


 
Мефисто   (2006-05-03 20:00) [1]

// далее идет довольно большой блок операций с MRA и вызовом проедуры MRACalc

Вот его бы и желательно лицезреть


 
justnick   (2006-05-03 20:56) [2]

вот полное описание структуры
 TMyRecord = record
   X1,Y1: Double;
   X2,Y2: Double;
   X3,Y3: Double;
   ai, bi, ci: Double;
   aj, bj, cj: Double;
   ak, bk, ck: Double;
   i, j, k: Integer;
   Pi,Pj,Pk: Double;
   Index: Integer;
   DIDPiPi, DIDPiPj, DIDPiPk, DIDPiC: Double;
   DIDPjPi, DIDPjPj, DIDPjPk, DIDPjC: Double;
   DIDPkPi, DIDPkPj, DIDPkPk, DIDPkC: Double;
   UP: Boolean;
   Calculated: Boolean;
 end;


 
justnick   (2006-05-03 20:56) [3]

это продолжение события на кнопке

 MRA[0].X1 := x1;
 MRA[0].Y1 := y1;
 MRA[0].X2 := x1 + l/2;
 MRA[0].Y2 := y1 + l * sqrt(3)/2;
 MRA[0].X3 := x1 - l/2;
 MRA[0].Y3 := y1 + l * sqrt(3)/2;
 MRA[0].up := true;
 MRA[0].Index := 1;
 MRA[0].i := 1;
 MRA[0].j := PCCount + 2;
 MRA[0].k := PCCount + 1;
 MRACalc(MRA[0]);

 for i := 0 to RCount - 1 do begin
   for j := 0 to CCount - 1 do begin
     if j + 1 < CCount then begin
       if MRA[i * CCount + j].UP then begin

         MRA[i * CCount + j + 1].UP := false;

         MRA[i * CCount + j + 1].X1 := MRA[i * CCount + j].X2;
         MRA[i * CCount + j + 1].Y1 := MRA[i * CCount + j].Y2;

         MRA[i * CCount + j + 1].X2 := MRA[i * CCount + j].X1;
         MRA[i * CCount + j + 1].Y2 := MRA[i * CCount + j].Y1;

         MRA[i * CCount + j + 1].X3 := MRA[i * CCount + j].X1 + l;
         MRA[i * CCount + j + 1].Y3 := MRA[i * CCount + j].Y1;

         MRA[i * CCount + j + 1].i := MRA[i * CCount + j].j;
         MRA[i * CCount + j + 1].j := MRA[i * CCount + j].i;
         MRA[i * CCount + j + 1].k := MRA[i * CCount + j].i + 1;
       end else begin

         MRA[i * CCount + j + 1].UP := true;

         MRA[i * CCount + j + 1].X1 := MRA[i * CCount + j].X3;
         MRA[i * CCount + j + 1].Y1 := MRA[i * CCount + j].Y3;

         MRA[i * CCount + j + 1].X2 := MRA[i * CCount + j].X1 + l;
         MRA[i * CCount + j + 1].Y2 := MRA[i * CCount + j].Y1;

         MRA[i * CCount + j + 1].X3 := MRA[i * CCount + j].X1;
         MRA[i * CCount + j + 1].Y3 := MRA[i * CCount + j].Y1;

         MRA[i * CCount + j + 1].i := MRA[i * CCount + j].k;
         MRA[i * CCount + j + 1].j := MRA[i * CCount + j].i + 1;
         MRA[i * CCount + j + 1].k := MRA[i * CCount + j].i;
       end;
     end else begin
       if MRA[i * CCount + j].UP then begin
         if (CCount mod 2) <> 0 then begin
           MRA[i * CCount + j + 1].UP := false;

           MRA[i * CCount + j + 1].X1 := MRA[(i-1) * CCount + j + 1].X3 + l/2;
           MRA[i * CCount + j + 1].Y1 := MRA[(i-1) * CCount + j + 1].Y3 + l*sqrt(3)/2;

           MRA[i * CCount + j + 1].X2 := MRA[(i-1) * CCount + j + 1].X3;
           MRA[i * CCount + j + 1].Y2 := MRA[(i-1) * CCount + j + 1].Y3;

           MRA[i * CCount + j + 1].X3 := MRA[(i-1) * CCount + j + 1].X2;
           MRA[i * CCount + j + 1].Y3 := MRA[(i-1) * CCount + j + 1].Y2;

           MRA[i * CCount + j + 1].i := PCCount*i+1;
           MRA[i * CCount + j + 1].j := MRA[(i-1) * CCount + j + 1].k;
           MRA[i * CCount + j + 1].k := MRA[(i-1) * CCount + j + 1].j;
         end else begin
           MRA[i * CCount + j + 1].UP := true;

           MRA[i * CCount + j + 1].X1 := MRA[(i-1) * CCount + j + 1].X1;
           MRA[i * CCount + j + 1].Y1 := MRA[(i-1) * CCount + j + 1].Y1;

           MRA[i * CCount + j + 1].X2 := MRA[(i-1) * CCount + j + 1].X1 + l/2;
           MRA[i * CCount + j + 1].Y2 := MRA[(i-1) * CCount + j + 1].Y1 + l * sqrt(3) / 2;

           MRA[i * CCount + j + 1].X3 := MRA[(i-1) * CCount + j + 1].X1 - l/2;
           MRA[i * CCount + j + 1].Y3 := MRA[(i-1) * CCount + j + 1].Y1 + l * sqrt(3) / 2;

           MRA[i * CCount + j + 1].i := MRA[(i-1) * CCount + j + 1].i;
           MRA[i * CCount + j + 1].j := PCCount*(i + 2)+2;
           MRA[i * CCount + j + 1].k := PCCount*(i + 2)+1;
         end;
       end else begin
         if (CCount mod 2) <> 0 then begin
           MRA[i * CCount + j + 1].UP := true;

           MRA[i * CCount + j + 1].X1 := MRA[(i-1) * CCount + j + 1].X1;
           MRA[i * CCount + j + 1].Y1 := MRA[(i-1) * CCount + j + 1].Y1;

           MRA[i * CCount + j + 1].X2 := MRA[(i-1) * CCount + j + 1].X1 + l/2;
           MRA[i * CCount + j + 1].Y2 := MRA[(i-1) * CCount + j + 1].Y1 + l * sqrt(3) / 2;

           MRA[i * CCount + j + 1].X3 := MRA[(i-1) * CCount + j + 1].X1 - l/2;
           MRA[i * CCount + j + 1].Y3 := MRA[(i-1) * CCount + j + 1].Y1 + l * sqrt(3) / 2;

           MRA[i * CCount + j + 1].i := MRA[(i-1) * CCount + j + 1].i;
           MRA[i * CCount + j + 1].j := PCCount*i+1;
           MRA[i * CCount + j + 1].k := PCCount*i+2;
         end else begin
           MRA[i * CCount + j + 1].UP := false;

           MRA[i * CCount + j + 1].X1 := MRA[(i-1) * CCount + j + 1].X3 + l/2;
           MRA[i * CCount + j + 1].Y1 := MRA[(i-1) * CCount + j + 1].Y3 + l*sqrt(3)/2;

           MRA[i * CCount + j + 1].X2 := MRA[(i-1) * CCount + j + 1].X3;
           MRA[i * CCount + j + 1].Y2 := MRA[(i-1) * CCount + j + 1].Y3;

           MRA[i * CCount + j + 1].X3 := MRA[(i-1) * CCount + j + 1].X2;
           MRA[i * CCount + j + 1].Y3 := MRA[(i-1) * CCount + j + 1].Y2;

           MRA[i * CCount + j + 1].i := PCCount*(i+2)+1;
           MRA[i * CCount + j + 1].j := MRA[(i-1) * CCount + j + 1].k;
           MRA[i * CCount + j + 1].k := MRA[(i-1) * CCount + j + 1].j;
         end;
       end;
     end;
    MRACalc(MRA[i * CCount + j + 1]);
   end;
 end;


 
justnick   (2006-05-03 20:58) [4]

это процедура пересчета структуры

procedure TForm1.MRACalc (var MR: TMyRecord);
begin
With MR do begin
 ai := X2 * Y3 - X3 * Y2;   // (XjYk - XkYj)
 aj := X3 * Y1 - X1 * Y3;   // (XkYi - XiYk)
 ak := X1 * Y2 - X2 * Y1;   // (XiYj - XjYi)

 bi := Y2 - Y3;             // (Yj - Yk)
 bj := Y3 - Y1;             // (Yk - Yi)
 bk := Y1 - Y2;             // (Yi - Yj)

 ci := X3 - X2;             // (Xk - Xj)
 cj := X1 - X3;             // (Xi - Xk)
 ck := X2 - X1;             // (Xj - Xi)

 DIDPiPi := 2*bi*bi*(1 - WxW_div_CxC*rebro*rebro/24) +
            2*ci*ci*(1 - WxW_div_CxC*rebro*rebro/ 8) -
            2*ai*ai*(WxW_div_CxC) -
            2*ai*ci*(WxW_div_CxC*rebro/sqrt(3));
 DIDPiPj := 2*bi*bj*(1 - WxW_div_CxC*rebro*rebro/24) +
            2*ci*cj*(1 - WxW_div_CxC*rebro*rebro/ 8) -
            2*ai*aj*WxW_div_CxC -
            (aj*ci + ai*cj)*(WxW_div_CxC*rebro/sqrt(3));
 DIDPiPk := 2*bi*bk*(1 - WxW_div_CxC*rebro*rebro/24) +
            2*ci*ck*(1 - WxW_div_CxC*rebro*rebro/ 8) -
            2*ai*ak*WxW_div_CxC -
            (ak*ci + ai*ck)*(WxW_div_CxC*rebro/sqrt(3));
//---------------------------------------------------------------------
 DIDPjPi := 2*bi*bj*(1 - WxW_div_CxC*rebro*rebro/24) +
            2*ci*cj*(1 - WxW_div_CxC*rebro*rebro/ 8) -
            2*ai*aj*WxW_div_CxC -
            (aj*ci + ai*cj)*(WxW_div_CxC*rebro/sqrt(3));
 DIDPjPj := 2*bj*bj*(1 - WxW_div_CxC*rebro*rebro/24) +
            2*cj*cj*(1 - WxW_div_CxC*rebro*rebro/ 8) -
            2*aj*aj*WxW_div_CxC -
            2*aj*cj*(WxW_div_CxC*rebro/sqrt(3));
 DIDPjPk := 2*bj*bk*(1 - WxW_div_CxC*rebro*rebro/24) +
            2*cj*ck*(1 - WxW_div_CxC*rebro*rebro/ 8) -
            2*aj*ak*WxW_div_CxC -
            (ak*cj + aj*ck)*(WxW_div_CxC*rebro/sqrt(3));
//---------------------------------------------------------------------
 DIDPkPi := 2*bi*bk*(1 - WxW_div_CxC*rebro*rebro/24) +
            2*ci*ck*(1 - WxW_div_CxC*rebro*rebro/ 8) -
            2*ai*ak*WxW_div_CxC -
            (ak*ci + ai*ck)*(WxW_div_CxC*rebro/sqrt(3));
 DIDPkPj := 2*bj*bk*(1 - WxW_div_CxC*rebro*rebro/24) +
            2*cj*ck*(1 - WxW_div_CxC*rebro*rebro/ 8) -
            2*aj*ak*WxW_div_CxC -
            (ak*cj + aj*ck)*(WxW_div_CxC*rebro/sqrt(3));
 DIDPkPk := 2*bk*bk*(1 - WxW_div_CxC*rebro*rebro/24) +
            2*ck*ck*(1 - WxW_div_CxC*rebro*rebro/ 8) -
            2*ak*ak*WxW_div_CxC -
            2*ak*ck*(WxW_div_CxC*rebro/sqrt(3));

 Calculated := true;
end;
end;

все вышенаписанное работает без ошибок, за исключением той о которой говорил в первом посте


 
Мефисто   (2006-05-03 21:13) [5]

Вах!... Черт ногу в этом коде сломит =)

Еще бы покажи чего  MRACalc(); делает внутри.

>> for i := 0 to RCount - 1 do begin

Всегда ли выполняется данный цикл?


 
Мефисто   (2006-05-03 21:19) [6]

Вах!... Черт ногу сломит в таком коде =)

Еще покажи MRACalc ();

>>   for i := 0 to RCount - 1 do begin
>>   for j := 0 to CCount - 1 do begin

Всегда ли 100% вероятностью выполняются данные условия т.е. циклы?


 
Мефисто   (2006-05-03 21:20) [7]

Вах!... Черт ногу сломит в таком коде =)

Еще покажи MRACalc ();

>>   for i := 0 to RCount - 1 do begin
>>   for j := 0 to CCount - 1 do begin

Всегда ли 100% вероятностью выполняются данные условия т.е. циклы?


 
evvcom ©   (2006-05-03 22:52) [8]


> for i := 0 to RCount - 1 do begin
>    for j := 0 to CCount - 1 do begin
>      if j + 1 < CCount then begin
>        if MRA[i * CCount + j].UP then begin

Скорее всего происходит выход за границы массива MRA. Если бы указал, чему равны RCount, CCount и N, то может и получил бы уже тык пальцем. И еще, галка Range Checking стоит?


 
Loginov Dmitry ©   (2006-05-03 23:20) [9]

Код абсолютно нечитабелен. Оценил бы на 2 с двумя минусами.
По сабжу: почему бы не сделать массив двухмерным - бесконечный расчет смещений может вас сильно запутать.


 
Slym ©   (2006-05-04 05:09) [10]

1. Нечитабелен и тормознут
ты скока раз написал строку:
i * CCount + j + 1 и (i-1) * CCount + j + 1 ?
каждый раз индекс вычисляется и смещение в блоке памяти...

2. Двухмерная работа с одномерным массивом? Делай двухмерный массив! Или масссив of массив

MRACalc вынеси из объекта - на 1 параметр сократишЪ стек: быстрее будет

justnick   (03.05.06 19:53)
так вот. по завершению этого события массив IA деформируется. у него изменяется общее количество элементов, и сами значения элементов тоже меняются, вплоть до чисел с плавающей точкой

ясен пень... указатель на массив уже не действителен а ты его дебагером... а тот блок памяти уже кто-то занял вот ты и видишь мусор через призму своего TMyRecord...
Зачем временные переменные описывать в классе? объявляй, создавай и оперируй ими в процедуре.


 
Slym ©   (2006-05-04 05:12) [11]

justnick   (03.05.06 19:53)
Подскажите плз где лажанулся, а то не охота потенциальную багу оставлять.

В итоге ты лажанулся с дебагером: нефиг смотреть по недействительному указателю


 
TUser ©   (2006-05-04 08:50) [12]

Предположу, что все нумеруется с нуля, в RCount и CCount - число стро и столбцов в некоторой таблице. Тогда у тебя написано слудующее

for i := 0 to RCount - 1 do begin
  for j := 0 to CCount - 1 do begin
    if j + 1 < CCount then begin
     
      {j < CCount - 1
      тут используются
      MRA[i * CCount + j + 1]
      MRA[i * CCount + j]}

    end else begin

      {j = CCount - 1
      тут используются
      MRA[i * CCount + j + 1] // при i = RCount выходим за границу массива
      MRA[(i-1) * CCount + j + 1]}
      ...



 
Loginov Dmitry ©   (2006-05-04 08:55) [13]


> Slym ©   (04.05.06 05:09) [10]
> Slym ©   (04.05.06 05:12) [11]


Какие классы? Какой стек? Какие указатели?

Зачем вводить человека в заблуждение?


 
evvcom ©   (2006-05-04 09:36) [14]


> MRACalc вынеси из объекта - на 1 параметр сократишЪ стек:
>  быстрее будет

Self передается здесь через eax, а не через стек.


 
justnick   (2006-05-04 12:14) [15]

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


 
justnick   (2006-05-04 12:16) [16]

2.все массивы глобальные... плюс отключал оптимайзер..... ну а стал я заниматься этим только после того как стало глючить обращение к IA (он тоже глобальный) в другой процедуре


 
justnick   (2006-05-04 12:20) [17]

3. если бы были выходы за границы массива MRA то тогда бы ругалось инвалид пойнтер операшинами.... все циклы выполняются, т.к. RCount и CCount всегда больше нуля, а RCount * CCount = N ...  с Range Checking ща погляжу


 
ЮЮ ©   (2006-05-04 12:21) [18]

[i, j] = i * CCount + j
Поэтому конструкцию MRA[i * CCount + j + 1  лучше не использовать. В этом случае лучше индекс j правильго менять. Да и вычислить  i * CCount + j  один раз в начале внутреннего цикла - и символов меньше и смысл очевиднее


 
justnick   (2006-05-04 12:23) [19]

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


 
justnick   (2006-05-04 12:26) [20]

5. еще заметил если в коде MRACalc не вызывать, или вызывать но с пустым телом то все ОК. все начинается когда повялется математика в MRACalc типа
with MR do
ai := X2 * Y3 - X3 * Y2;


 
ЮЮ ©   (2006-05-04 12:30) [21]

Какой "математический" смысл имеет MRA[i * CCount + j + 1]
на последней итерации циклов, кроме как попытки вылезть за пределы массива? :)


 
ЮЮ ©   (2006-05-04 12:38) [22]

>5. еще заметил если в коде MRACalc не вызывать,
Естественно, если память не портить, то сама она портиться не станет. И, наоборот, если она "портится", то во всем виноват твой код.


 
Sapersky   (2006-05-04 12:44) [23]

Физически одномерный двумерный массив:

PMyRecArr = ^TMyRecArr;
TMyRecArr = array [0..0] of TMyRecord;    

PMyRecArr2D  =^TMyRecArr2D;
TMyRecArr2D = array [0..0] of PMyRecArr;  

Var Arr : PMyRecArr2D;
begin
GetMem(Arr, Width * Height * SizeOf(TMyRecord));
for y := 0 to Height - 1 do begin
 for x := 0 to Width - 1 do begin
   Arr[y,x] := ... // индексы пишутся в обратном порядке

Ещё одна особенность - т.к. это не динамический массив, а типизированный указатель - посмотреть его содержимое отладчиком нельзя.


 
justnick   (2006-05-04 12:49) [24]

мля.... я неисправимо туп... дейтсвительно вылезает за рамки..... только вот оно обычно еррор раньше выкидывало :-) звыняйте за флуд

ПС. мне нужно к массиву обращаться как MRA[i] (через один индекс а не через два, а два индекса нужны только чтобы координаты узлов посчитать)  массив по условиям задачи одномерный при любом раскладе


 
TUser ©   (2006-05-04 14:39) [25]

> 1. массив одномерный потому что он мне физически нужен одномерный,

Физически он всегда будет одномерным. В 2-мерном D возьмет насебя всю эту индексную арифметику.

>  он должен быть глобальный поскольку нужен в других процедурах

Да ради бога.

> если бы были выходы за границы массива MRA то тогда бы ругалось инвалид пойнтер операшинами

не факт.


 
Sapersky   (2006-05-04 16:15) [26]

> 1. массив одномерный потому что он мне физически нужен одномерный,
Физически он всегда будет одномерным


Наверное имелась в виду нефрагментированность, т.е. чтобы "одним куском".
А двумерный динамический массив (array of array of TMyRecord), это, вроде как, массив одномерных динамических массивов (указателей), со всеми вытекающими.



Страницы: 1 вся ветка

Текущий архив: 2006.06.11;
Скачать: CL | DM;

Наверх




Память: 0.56 MB
Время: 0.043 c
2-1148705317
Urvin
2006-05-27 08:48
2006.06.11
Проверка наличия файла


2-1148469253
Konnor
2006-05-24 15:14
2006.06.11
Инет


15-1147593844
Волька
2006-05-14 12:04
2006.06.11
Учёт компьютерной техники


1-1146505428
Sysanin
2006-05-01 21:43
2006.06.11
защита от принт скрина


15-1147757331
Ega23
2006-05-16 09:28
2006.06.11
С Днём Рождения! 16 мая