Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / record и очень динамические массивы / 16 сообщений из 16, страница 1 из 1
27.12.2018, 16:30
    #39754010
Tim Woo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
Добрый день!
Имеется вот такая record:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
type TAnswers = record
    nQ  : Integer;
    nQS : Integer;
    nM  : Integer;
    nD  : Integer;
    nnD : array of Integer;
    Keys : array of Char;
    Names : array of array of string;
    Results   : array of array of Char;
    Matrix    : array of array of Integer;
    Relevance : array of array of Integer;
    Total     : array of array of Real;
    Correct   : array of Integer;
    Diff      : array of Real;
    P         : array of Real;
    Q         : array of Real;
    PQ        : array of Real;
    PQs       : Real;
    DI        : array of Real;
    Variance  : Real;
    PKR20     : Real;
    SEM       : Real;
    AvDiff    : Real;
    AvDI      : Real;
    AvTotal   : Real;
  end;



Имеется переменная Data, которая TAnswers.

Ситуация N1 - Создание и заполнение переменной Data "с нуля".
Пользователь указывает два числа, которые позже станут Data.nQ и Data.nM.
После этого все массивы из Data должны будут создаться под размеры nQ, nM или nQ-x-nM.
Все массивы должны быть "обнуленными": числовые = 0; строки = ''; чары = #0;

Сейчас это все у меня делается вот так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
procedure TFormMain.SetTAnswers;
begin
  with Data do begin
      nQ := StrToInt(QN.Text);                
      nQS := nQ;                             
      nM := StrToInt(QM.Text);                             
      nD := StrToInt(DN.Text)
      SetLength(nnD, nD);
      SetLength(Keys, nQ);
      SetLength(Names, nM, 2);
      SetLength(Results, nM, nQ);
      SetLength(Matrix, nM, nQ);
      SetLength(Relevance, 5, nQ);
      SetLength(Total, nM, nD);
      SetLength(Correct, nQ);
      SetLength(Diff, nQ);
      SetLength(P, nQ);
      SetLength(Q, nQ);
      SetLength(PQ, nQ);
      SetLength(DI, nQ);  
      PQs := 0;
      Variance  := 0;
      PKR20     := 0;
      SEM       := 0;
      AvDiff    := 0;
      AvDI      := 0;
      AvTotal   := 0;
  end;
end; 



Вопросы:
Правильно ли я создаю динамические массивы в пределах указанной record?
Будут ли создаваемые массивы всегда пустыми? Или же их нужно обнулять для 100% уверенности, что при обращении к "пустому" массиву в нем будет мусор вместо пустых значений?

Ситуация N2 - Пересоздание и перезаполнение переменной Data.
Уже имеется переменная Data, где все массивы-переменные заполнены рабочими данными. Пользователь вводит новые значения, которые станут в последствии Data.nM и Data.nQ.
Вопрос:
Как правильно "убить/сбросить/обнулить" ранее созданную переменную типа record, чтобы пересоздать ее вновь, вместе с новыми размерами внутренних динамических массивов с нулевыми значениями?
...
Рейтинг: 0 / 0
27.12.2018, 16:36
    #39754014
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
ДокументацияExisting characters in the string or elements in the array are preserved, but the content of newly allocated space is undefined.
т.е. новые элементы нужно обнулять.
...
Рейтинг: 0 / 0
27.12.2018, 16:38
    #39754017
RWolf
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
Tim WooВопрос:
Как правильно "убить/сбросить/обнулить" ранее созданную переменную типа record, чтобы пересоздать ее вновь, вместе с новыми размерами внутренних динамических массивов с нулевыми значениями?
Finalize()
...
Рейтинг: 0 / 0
27.12.2018, 16:52
    #39754028
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
Data:=Default(TAnswers);
...
Рейтинг: 0 / 0
27.12.2018, 17:12
    #39754049
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
Tim WooПравильно ли я создаю динамические массивы в пределах указанной record?Да
Tim WooБудут ли создаваемые массивы всегда пустыми?Нет. Там будет мусор
Tim WooКак правильно "убить/сбросить/обнулить" ранее созданную переменную типа record, чтобы пересоздать ее вновь,Незачем. Просто установите новые значения
...
Рейтинг: 0 / 0
27.12.2018, 17:22
    #39754053
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
_Vasilisk_Нет. Там будет мусор
Динамические массивы всегда обнуляются.
...
Рейтинг: 0 / 0
27.12.2018, 17:32
    #39754067
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
Сказал же уже: Data:=Default(TAnswers);

Это полностью обнулит рекорд.
...
Рейтинг: 0 / 0
27.12.2018, 17:46
    #39754087
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
Kazantsev AlexeyДинамические массивы всегда обнуляются.Только для managed типов
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
procedure DynArraySetLength(var a: Pointer; typeInfo: Pointer; dimCnt: NativeInt; lengthVec: PNativeint);
var
  i,j: NativeInt;
  newLength, oldLength, minLength: NativeInt;
  elSize: NativeInt;
  neededSize: NativeInt;
  p, pp: Pointer;
begin
  p := a;

  // Fetch the new length of the array in this dimension, and the old length
  newLength := lengthVec^;
  if newLength <= 0 then
  begin
    if newLength < 0 then
      Error(reRangeError);
    DynArrayClear(a, typeInfo);
    exit;
  end;

  oldLength := 0;
  if p <> nil then
  begin
    Dec(PByte(p), SizeOf(TDynArrayRec));
    oldLength := PDynArrayRec(p).Length;
  end;

  // Calculate the needed size of the heap object
  Inc(PByte(typeInfo), PDynArrayTypeInfo(typeInfo).name);
  elSize := PDynArrayTypeInfo(typeInfo).elSize;
  if PDynArrayTypeInfo(typeInfo).elType <> nil then
    typeInfo := PDynArrayTypeInfo(typeInfo).elType^
  else
    typeInfo := nil;
  neededSize := newLength*elSize;
  if neededSize div newLength <> elSize then
    Error(reRangeError);
  Inc(neededSize, SizeOf(TDynArrayRec));
  if neededSize < 0 then
    Error(reRangeError);

  // If the heap object isn't shared (ref count = 1), just resize it. Otherwise, we make a copy
  if (p = nil) or (PDynArrayRec(p).RefCnt = 1) then
  begin
    pp := p;
{$IF not Defined(WEAKREF)}
    if (newLength < oldLength) and (typeInfo <> nil) then
      FinalizeArray(PByte(p) + SizeOf(TDynArrayRec) + newLength*elSize, typeInfo, oldLength - newLength);
{$ELSE}
    if typeInfo <> nil then
    begin
      if newLength < oldLength then
        minLength := newLength
      else
        minLength := oldLength;
      GetMem(pp, neededSize);
      FillChar((PByte(pp) + SizeOf(TDynArrayRec))^, minLength * elSize, 0);
      if p <> nil then
      begin
        CopyArray(PByte(pp) + SizeOf(TDynArrayRec), a, typeInfo, minLength);
        FinalizeArray(PByte(p) + SizeOf(TDynArrayRec), typeInfo, oldLength);
        FreeMem(p);
      end;
    end else
{$ENDIF}
      ReallocMem(pp, neededSize);
    p := pp;
  end
  else
  begin
    Dec(PDynArrayRec(p).RefCnt);
    GetMem(p, neededSize);
    minLength := oldLength;
    if minLength > newLength then
      minLength := newLength;
    if typeInfo <> nil then
    begin
      FillChar((PByte(p) + SizeOf(TDynArrayRec))^, minLength*elSize, 0);
      CopyArray(PByte(p) + SizeOf(TDynArrayRec), a, typeInfo, minLength)
    end
    else
      Move(PByte(a)^, (PByte(p) + SizeOf(TDynArrayRec))^, minLength*elSize);
  end;

  // The heap object will now have a ref count of 1 and the new length
  PDynArrayRec(p).RefCnt := 1;
  PDynArrayRec(p).Length := newLength;
  Inc(PByte(p), SizeOf(TDynArrayRec));

  // Set the new memory to all zero bits
  if newLength > oldLength then
    FillChar((PByte(p) + elSize * oldLength)^, elSize * (newLength - oldLength), 0);

  // Take care of the inner dimensions, if any
  if dimCnt > 1 then
  begin
    Inc(lengthVec);
    Dec(dimCnt);
    i := 0;
    try
      while i < newLength do
        begin
          DynArraySetLength(PPointerArray(p)[i], typeInfo, dimCnt, lengthVec);
          Inc(i);
        end;
    except
	  // Free arrays on exception
	  for j := 0 to i  do
		DynArrayClear(PPointerArray(p)[j],typeInfo);
	  DynArrayClear(p,typeinfo);
	  raise;
    end;
  end;
  a := p;
end;

...
Рейтинг: 0 / 0
27.12.2018, 17:47
    #39754088
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
rgreatЭто полностью обнулит рекорд.Ему не нужно обнулять. Ему нужно перезаписать и он интересуется, нужно ли вызывать какой-нибудь деструктор
...
Рейтинг: 0 / 0
27.12.2018, 17:59
    #39754096
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
_Vasilisk_Ему не нужно обнулять. Ему нужно перезаписатьДля рекорда это одно и тоже.
...
Рейтинг: 0 / 0
27.12.2018, 18:01
    #39754098
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
rgreatДля рекорда это одно и тоже.Так зачем вначале обнулять, чтобы потом переписывать? Не проще ли сразу переписать?
...
Рейтинг: 0 / 0
27.12.2018, 18:13
    #39754107
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
_Vasilisk_Только для managed типов
Для всех:
http://docwiki.embarcadero.com/Libraries/Rio/en/System.SetLength For a dynamic array variable, SetLength reallocates the array referenced by S to the given length. Existing elements in the array are preserved and newly allocated space is set to 0 or nil. For multidimensional dynamic arrays, SetLength may take more than one-length parameter (up to the number of array dimensions). Each parameter specifies the number of elements along a particular dimension.
...
Рейтинг: 0 / 0
27.12.2018, 18:53
    #39754138
Tim Woo
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
Так. Для второй проблемы решил использовать
Data:=Default(TAnswers);
Чтоб уж наверняка.

По поводу "обнулений" - получается что все таки будет забит нулями?
А то из всего диалога не особо понятно :)
...
Рейтинг: 0 / 0
27.12.2018, 19:12
    #39754148
rgreat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
_Vasilisk_rgreatДля рекорда это одно и тоже.Так зачем вначале обнулять, чтобы потом переписывать? Не проще ли сразу переписать?Так лаконичней.
...
Рейтинг: 0 / 0
27.12.2018, 19:20
    #39754153
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
Kazantsev AlexeyДля всех:Таки да. Недоглядел
_Vasilisk_
Код: pascal
1.
2.
3.
  // Set the new memory to all zero bits
  if newLength > oldLength then
    FillChar((PByte(p) + elSize * oldLength)^, elSize * (newLength - oldLength), 0);



Tim WooПо поводу "обнулений" - получается что все таки будет забит нулями?Получается, что будет. В Delphi 2007 уже обнуление есть
...
Рейтинг: 0 / 0
28.12.2018, 09:30
    #39754344
Beltar
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
record и очень динамические массивы
Динамический массив - это ссылочный тип. => В каждой структуре отдельно выделяй память и очищай или как-то явно инициализируй.
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / record и очень динамические массивы / 16 сообщений из 16, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]