Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.06.11;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.013 c
2-1148361462
Konnor
2006-05-23 09:17
2006.06.11
Reboot


15-1148034709
saxon
2006-05-19 14:31
2006.06.11
Задачка про гномов


2-1148464871
webpauk
2006-05-24 14:01
2006.06.11
Установить курсор


15-1147704023
Константинов
2006-05-15 18:40
2006.06.11
Вопрос Москвичам


1-1146820596
Delphi5.01
2006-05-05 13:16
2006.06.11
Получение handle-а активного компонента (вне рабочей формы)





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский