Структуры, массивы и копирование

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

Структуры, массивы и копирование

Сообщение thief » 09.12.2015 13:51:25

Здравствуйте, уважаемые жители форума!
Есть несколько вопросов по структурам и типам в целом. Вроде и начитался везде всего что мог, но бардак в голове только сильнее стал (особенно от других языков программирования), а хотелось бы систематизировать это все.
Вот тестовый код:
Код: Выделить всё
type
  TFMfn = array[0..9] of char;
  TFMdatetime = array[0..4] of byte;

  TFMFactoryNumber = packed record
    lfn: TFMfn;
    ldatetime: TFMdatetime;
    lcrc: word;
  end;
  PFMFactoryNumber = ^TFMFactoryNumber;

  TFMres = packed record
    lfrom: word;
    ldate: TFMdate;
    lcrc: word;
  end;
  PFMres = ^TFMres;

  TFMv4 = packed record
    FactNum: TFMFactoryNumber;
    Res: array of TFMres;
  end;
  PFMv4 = ^TFMv4;

function IntToFMdatetime(day, month, year, hour, minute: byte): TFMdatetime;
begin
  Result[0]:=day;
  Result[1]:=month;
  Result[2]:=year;
  Result[3]:=hour;
  Result[4]:=minute;
end;
procedure FMcopy( );
var
  fm1,fm2: TFMv4;
begin
  fm1.FactNum.lfn:='1234567890';
  fm1.FactNum.ldatetime := IntToFMdatetime(0,1,2,3,4);
  SetLength(fm1.Res,2);
  fm1.Res[0].lfrom:=11;
  fm1.Res[1].lfrom:=22;
  fm2.Res := Copy(fm1.Res);
  fm2.FactNum.lfn:='2224567890';
  fm2.FactNum.ldatetime := IntToFMdatetime(9,2,7,3,4);
  fm2.Res[0].lfrom:=111;
end;
begin
  FMcopy();
end.

И немножко вопросов:
  1. Я так понимаю TFMFactoryNumber и TFMres содержат в себе только типы-значения и память переменным выделяется/освобождается автоматически при попадании/покидании области видимости.
  2. TFMv4 содержит в себе тип-значение TFMFactoryNumber и ссылочный "тип" array of TFMres. Память под FactNum выделяется автоматически, а под Res изначально не выделяется и ее необходимо выделить вручную через SetLengh.
  3. Вопрос по функции Copy(fm1.Res). Я нашел только описание с тремя параметрами Function Copy(A : DynArrayType; Index,Count : Integer) : DynArray;, как она работает только с одним?
  4. Вопрос по ресурсам. fm1.Res и fm2.Res фактически указатели на динамические массивы (или я не ошибаюсь?), при покидании области видимости процедуры FMcopy, уничтожатся ли самостоятельно динамические массивы Res вместе с fm1 и fm2?
thief
незнакомец
 
Сообщения: 2
Зарегистрирован: 09.12.2015 11:40:03

Re: Структуры, массивы и копирование

Сообщение Pavia » 09.12.2015 21:16:03

1. Память для переменных вида значения автоматически выделяется и освобождается только для локальных переменных. Для глобальных она постоянна.
2.
ссылочный "тип" array of TFMres
Вы, не там кавычки поставили :D
"ссылочный" тип array of TFMres
Считайте что это не ссылочный тип, а тип динамического массива. Ссылочным он является из-за своего внутреннего представления.
3. Плохо искали в справке всё описано. А работает с 1 при помощи магии компилятора.
4. Для динамических массивов и строк, память освобождать не надо она очищается автоматически по выходу из процедур и функций.
Если вы будете работать с fm1.Res и fm2.Res как с указателями, то велика вероятность нарушить внутреннее устройство динамических массивов.
Тогда может получиться всё что угодно.
5. Выше написанное не относиться к динамическим переменным. Там вам надо будет самим очистить указатели. И только после вы сможете использованием SetLength для выделения памяти. А для освобождения памяти вам уже вручную надо будет сделать SetLength(0).
Аватара пользователя
Pavia
постоялец
 
Сообщения: 290
Зарегистрирован: 07.01.2011 12:46:51

Re: Структуры, массивы и копирование

Сообщение thief » 10.12.2015 11:25:27

Благодарю за ответ!
Можно ли делать так:
Код: Выделить всё
fm2 := fm1;
fm2.Res := Copy(fm1.Res);

или так:
Код: Выделить всё
fm2 := fm1;
fm2.Res := nil;
fm2.Res := Copy(fm1.Res);

Первое вроде точно неправильно. Особенно, если fm1.Res и fm2.Res имели разный размер. Освободится ли память сама у fm2.Res перед присвоением?
А второе выглядит правильнее.

И еще ситуация:
fm1 - локальная переменная в процедуре.
fm2 - глобальная (или передается в процедуру через var)
В процедуре присваивается
Код: Выделить всё
fm2 := fm1

Будет ли нормально чувствовать себя fm2.Res при покидании области видимости процедуры?

P.S. Понимаю, что вопросы нубские и много раз задавались, но поиск по форуму еще больше запутывает.
thief
незнакомец
 
Сообщения: 2
Зарегистрирован: 09.12.2015 11:40:03

Re: Структуры, массивы и копирование

Сообщение Дож » 14.12.2015 15:45:38

Pavia писал(а):2.
ссылочный "тип" array of TFMres
Вы, не там кавычки поставили :D
"ссылочный" тип array of TFMres
Считайте что это не ссылочный тип, а тип динамического массива. Ссылочным он является из-за своего внутреннего представления.

Не только, ещё и поведением на него похож :)
Код: Выделить всё
var
  X, Y: array of LongInt;
begin
  SetLength(X, 5);
  X[4] := 0;
  Y := X;
  X[4] := 3;
  Writeln(Y[4]); // напечатает 3
end.
Аватара пользователя
Дож
энтузиаст
 
Сообщения: 899
Зарегистрирован: 12.10.2008 16:14:47


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 17

Рейтинг@Mail.ru