Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «О Ρ‡Ρ‘ΠΌ Π½Π΅ ΠΏΠΈΡˆΡƒΡ‚ Π² ΠΊΠ½ΠΈΠ³Π°Ρ… ΠΏΠΎ DelphiΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 107

Автор А. Π“Ρ€ΠΈΠ³ΠΎΡ€ΡŒΠ΅Π²

Π Π°Π½Π΅Π΅ ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ записСй, содСрТащих поля Ρ‚ΠΈΠΏΠ° AnsiString, Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΎΠ΄Π½ΠΎΠ³ΠΎ процСсса маскируСт ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ, Ρ‚.ΠΊ. ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ остаСтся допустимым ΠΈ Π΄Π°ΠΆΠ΅ (ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ врСмя) ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΌ. Но сСйчас с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½ΠΎΠ³ΠΎ Π² листингС 3.41 ΠΊΠΎΠ΄Π° (ΠΏΡ€ΠΈΠΌΠ΅Ρ€ RecordCopy Π½Π° ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС) ΠΌΡ‹ ΡƒΠ²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π½Π΅ исчСзаСт, Π° просто становится ΠΌΠ΅Π½Π΅Π΅ Π·Π°ΠΌΠ΅Ρ‚Π½ΠΎΠΉ.

Листинг 3.41. ΠŸΠΎΠ±ΠΎΡ‡Π½ΠΎΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ послС Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠ³ΠΎ копирования

type

 TSomeRecord = record

  SomeField: Integer;

  Str: string;

 end;


procedure TForm1.Button1Click(Sender: TObject);

var

 Rec: TSomeRecord;

 S: string;

 procedure CopyRecord;

 var

  LocalRec: TSomeRecord;

 begin

  LocalRec.SomeField := 10;

  LocalRec.Str := 'Hello!!!';

  UniqueString(LocalRec.Str);

  Move(LocalRec, Rec, SizeOf(TSomeRecord));

 end;

begin

 CopyRecord;

 S := 'Good bye';

 UniqueString(S);

 Label1.Caption := Rec.Str;

 Pointer(Rec.Str) := nil;

end;

На экранС вмСсто ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ³ΠΎ Hello!!! появится Good bye. Π­Ρ‚ΠΎ происходит Π²ΠΎΡ‚ ΠΏΠΎΡ‡Π΅ΠΌΡƒ: ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Move осущСствляСт простоС ΠΏΠΎΠ±Π°ΠΉΡ‚Π½ΠΎΠ΅ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠΉ области памяти Π² Π΄Ρ€ΡƒΠ³ΡƒΡŽ, ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ измСнСния счСтчика ссылок ΠΏΡ€ΠΈ этом Π½Π΅ срабатываСт. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ памяти Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π·Π½Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ локальной ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ CopyRecord ΠΎΡΡ‚Π°ΡŽΡ‚ΡΡ ссылки Π½Π° строку "Hello!!!". ΠŸΠ°ΠΌΡΡ‚ΡŒ, выдСлСнная этой строкС, освобоТдаСтся. Но Rec.Str ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° эту ΡƒΠΆΠ΅ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π΅Π½Π½ΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ. Для строки S выдСляСтся свободная ΠΏΠ°ΠΌΡΡ‚ΡŒ β€” Ρ‚Π° самая, Π³Π΄Π΅ Ρ€Π°Π½ΡŒΡˆΠ΅ Π±Ρ‹Π»Π° строка LocalRec.Str. А ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Rec.Str ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° эту ΠΎΠ±Π»Π°ΡΡ‚ΡŒ памяти, поэтому ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΊ Π½Π΅ΠΉ Π΄Π°Π΅Ρ‚ строку "Good bye", которая Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ Ρ‚Π°ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π°.

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π° послСднюю строку β€” ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Rec.Str ΠΊ Ρ‚ΠΈΠΏΡƒ Pointer ΠΈ ΠΎΠ±Π½ΡƒΠ»Π΅Π½ΠΈΡŽ. Π­Ρ‚ΠΎ сдСлано для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ памяти Π½Π΅ пытался Ρ„ΠΈΠ½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ строку Rec.Str послС Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹, ΠΈΠ½Π°Ρ‡Π΅ ΠΎΠ½ попытаСтся ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ ΠΏΠ°ΠΌΡΡ‚ΡŒ, которая ΡƒΠΆΠ΅ освобоТдСна, ΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ ошибка.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ, насколько ΠΊΠΎΠ²Π°Ρ€Π½Π° эта ошибка, рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄ (листинг 3.42, ΠΈΠ· Ρ‚ΠΎΠ³ΠΎ ΠΆΠ΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° RecordCopy Π½Π° ΠΊΠΎΠΌΠΏΠ°ΠΊΡ‚-дискС). 

Листинг 3.42. Π‘ΠΎΠΊΡ€Ρ‹Ρ‚ΠΈΠ΅ ошибки ΠΏΡ€ΠΈ Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²ΠΎΠΌ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ записи со строкой

procedure TForm1.Button2Click(Sender: TObject);

var

 Rec: TSomeRecord;

 S: string;

 procedure CopyRecord;

 var

  LocalRec: TSomeRecord;

 begin

  LocalRec.SomeField := 10;

  LocalRec.Str := 'ΠŸΡ€ΠΈΠ²Π΅Ρ‚!';

  Move(LocalRec, Rec, SizeOf(TSomeRecord));

 end;

begin

 CopyRecord; S := 'Пока!';

 Label1.Caption := Rec.Str;

end;

Or ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅Π³ΠΎ случая этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€ отличаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Π² Π½Π΅ΠΌ Π½Π΅Ρ‚ Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² UniqueString, ΠΈ строки ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ Π½Π° Π»ΠΈΡ‚Π΅Ρ€Π°Π»Ρ‹ Π² сСгмСнтС ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ ΡƒΠ΄Π°Π»ΡΡŽΡ‚ΡΡ. На экранС ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π²ΠΏΠΎΠ»Π½Π΅ ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ΅ ΠŸΡ€ΠΈΠ²Π΅Ρ‚!. ΠžΠ±Π½ΡƒΠ»ΡΡ‚ΡŒ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ здСсь ΡƒΠΆΠ΅ Π½Π΅Ρ‚ смысла, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Ρ‚ΡŒ Π»ΠΈΡ‚Π΅Ρ€Π°Π» ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ памяти всС Ρ€Π°Π²Π½ΠΎ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚. Π’Π°ΠΊ ошибка оказалась скрытой.

ΠŸΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΠΌ наши экспСримСнты. Запустим ΠΏΡ€ΠΈΠΌΠ΅Ρ€ RecordCopy ΠΈ ΠΏΠΎΠ½Π°ΠΆΠΈΠΌΠ°Π΅ΠΌ ΠΏΠΎΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΊΠ½ΠΎΠΏΠΊΠΈ Button1 ΠΈ Button2. ΠœΡ‹ Π²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π½Π΅ зависит ΠΎΡ‚ порядка, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΌΡ‹ Π½Π°ΠΆΠΈΠΌΠ°Π΅ΠΌ ΠΊΠ½ΠΎΠΏΠΊΠΈ.

ΠœΠΎΠ΄ΠΈΡ„ΠΈΡ†ΠΈΡ€ΡƒΠ΅ΠΌ ΠΊΠΎΠ΄ Π² локальной ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π΅ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° Button1Click: ΡƒΠ±Π΅Ρ€Π΅ΠΌ ΠΈΠ· строки "Hello!!!" Π²ΠΎΡΠΊΠ»ΠΈΡ†Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π·Π½Π°ΠΊΠΈ, сократив Π΅Π΅ Π΄ΠΎ "Hello". Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°Π±Π»ΡŽΠ΄Π°Ρ‚ΡŒ интСрСсный эффСкт: Ссли послС запуска Π½Π°ΠΆΠ°Ρ‚ΡŒ сначала Button1, Ρ‚ΠΎ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ ΠΌΡ‹ Π½Π΅ Π·Π°ΠΌΠ΅Ρ‚ΠΈΠΌ. А Π²ΠΎΡ‚ Ссли ΠΊΠ½ΠΎΠΏΠΊΠ° Button2 Π±ΡƒΠ΄Π΅Ρ‚ Π½Π°ΠΆΠ°Ρ‚Π° Ρ€Π°Π½ΡŒΡˆΠ΅, Ρ‡Π΅ΠΌ Button1, Ρ‚ΠΎ ΠΏΡ€ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… наТатиях Button1 Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π²ΠΈΠ΄ΠΈΠΌΡ‹Ρ… эффСктов Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚. Π­Ρ‚ΠΎ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ строка "Hello" Π½Π΅ Ρ€Π°Π²Π½Π° ΠΏΠΎ Π΄Π»ΠΈΠ½Π΅ строкС "Good bye", поэтому размСстится Π»ΠΈ "Good bye" Π² Ρ‚ΠΎΠΌ ΠΆΠ΅ мСстС памяти, Π³Π΄Π΅ Ρ€Π°Π½ΡŒΡˆΠ΅ Π±Ρ‹Π»Π° "Hello", ΠΈΠ»ΠΈ Π² ΠΊΠ°ΠΊΠΎΠΌ-Ρ‚ΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΌ, зависит ΠΎΡ‚ истории выдСлСния ΠΈ освобоТдСния памяти. Если ΠΌΡ‹ Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ "с чистого листа", ΠΏΠ°ΠΌΡΡ‚ΡŒ послС строки "Hello" останСтся свободной, поэтому Ρ‚ΡƒΠ΄Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΡ‚Π°Π²ΠΈΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ Π΄Π»ΠΈΠ½Π½ΡƒΡŽ строку. А Π²ΠΎΡ‚ Ссли Ρ€Π°Π½ΡŒΡˆΠ΅ ΠΏΠ°ΠΌΡΡ‚ΡŒ ΡƒΠΆΠ΅ Π²Ρ‹Π΄Π΅Π»ΡΠ»Π°ΡΡŒ ΠΈ освобоТдалась (Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² TLabel), Ρ‚ΠΎ Ρ‚ΠΎΡ‚ кусочСк свободной памяти, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ достаточСн для "Hello", слишком ΠΌΠ°Π» для "Good bye", ΠΈ эта строка размСщаСтся Π² Π΄Ρ€ΡƒΠ³ΠΎΠΌ мСстС. А Ρ‚Π°ΠΌ, ΠΊΡƒΠ΄Π° ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Rec.Str, остаСтся мусор, Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ Π½ΠΎΡ€ΠΌΠ°Π»ΡŒΠ½ΠΎ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, поэтому ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ΅ ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ Π΅Π³ΠΎ свойству Label1.Caption послСднСС Π½Π΅ мСняСтся (эффСкт Π½Π°Π±Π»ΡŽΠ΄Π°Π΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄ΠΎ Delphi 7 Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ; Π² Π±ΠΎΠ»Π΅Π΅ Π½ΠΎΠ²Ρ‹Ρ… вСрсиях Delphi ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π½ΠΎΠ²Ρ‹ΠΉ ΠΌΠ΅Π½Π΅Π΄ΠΆΠ΅Ρ€ памяти FastMem, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ строки Π² памяти, поэтому с Π½ΠΈΠΌ зависимости ΠΎΡ‚ порядка наТатия ΠΊΠ½ΠΎΠΏΠΎΠΊ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚).

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

Если ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ Π΄Π»ΠΈΠ½Ρƒ строки "ΠŸΡ€ΠΈΠ²Π΅Ρ‚!" хотя Π±Ρ‹ Π½Π° ΠΎΠ΄ΠΈΠ½ символ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° Π±Ρ‹Π»Π° Π½Π΅ ΠΊΠΎΡ€ΠΎΡ‡Π΅, Ρ‡Π΅ΠΌ "Good bye" (ΠΈΠ»ΠΈ Π½Π°ΠΎΠ±ΠΎΡ€ΠΎΡ‚, ΡΠΎΠΊΡ€Π°Ρ‚ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Ρ‚Π°ΠΊ. Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΎ стало ΠΊΠΎΡ€ΠΎΡ‡Π΅ "Hello"), ΠΌΡ‹ снова ΡƒΠ²ΠΈΠ΄ΠΈΠΌ, Ρ‡Ρ‚ΠΎ порядок наТатия ΠΊΠ½ΠΎΠΏΠΎΠΊ Π½Π΅ влияСт Π½Π° Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚. Π­Ρ‚ΠΎ происходит ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ строка "Hello" размСщаСтся Ρ‚Π°ΠΌ, Π³Π΄Π΅ Ρ€Π°Π½ΡŒΡˆΠ΅ Π±Ρ‹Π»Π° строка "ΠŸΡ€ΠΈΠ²Π΅Ρ‚!", Π° Π²ΠΎΡ‚ "Good bye" Ρ‚Π°ΠΌ ΡƒΠΆΠ΅ Π½Π΅ помСщаСтся. Если ΠΆΠ΅ ΠΎΠ±Π΅ строки Ρ‚Π°ΠΌ ΠΏΠΎΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ (ΠΈΠ»ΠΈ ΠΎΠ±Π΅ Π½Π΅ ΠΏΠΎΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ), ΠΎΠ½ΠΈ снова ΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚ΡΡ Π² ΠΎΠ΄Π½ΠΎΠΉ области памяти. Π’Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΡŒ ΠΌΠΎΠΆΠ΅Ρ‚ ΡΠΏΡ€ΠΎΡΠΈΡ‚ΡŒ: Π° ΠΏΡ€ΠΈ Ρ‡Π΅ΠΌ здСсь Π΄Π»ΠΈΠ½Π° строки "ΠŸΡ€ΠΈΠ²Π΅Ρ‚!", Ссли эта строка хранится Π² сСгмСнтС ΠΊΠΎΠ΄Π° ΠΈ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ освобоТдаСтся? Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ³Π΄Π° ΠΌΡ‹ присваиваСм эту строку свойству Label1.Caption, Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² TLabel происходит Π΅Π΅ пСрСнос Π² Π΄ΠΈΠ½Π°ΠΌΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ для Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… Π½ΡƒΠΆΠ΄ этого класса.

Π”Π°ΠΆΠ΅ Π½Π° Ρ‚Π°ΠΊΠΎΠΌ простом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π²ΠΈΠ΄Π½ΠΎ, насколько ΠΊΠΎΠ²Π°Ρ€Π½Π° эта ошибка ΠΈ ΠΊΠ°ΠΊ Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ измСнСния Π² ΠΊΠΎΠ΄Π΅ ΠΌΠΎΠ³ΡƒΡ‚ ΠΊΠ°Ρ€Π΄ΠΈΠ½Π°Π»ΡŒΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π΅ проявлСния. ΠœΠ΅ΠΆΠ΄Ρƒ Ρ‚Π΅ΠΌ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ здСсь ΠΊΠΎΠ΄ β€” ΠΏΠ»ΠΎΠ΄ Π΄ΠΎΠ»Π³ΠΎΠ³ΠΎ "приручСния" этой ошибки, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½Π° всСгда ΠΏΡ€ΠΎΡΠ²Π»ΡΠ»Π°ΡΡŒ прСдсказуСмым ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ. Но Π΄Π°ΠΆΠ΅ сСйчас ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π°Ρ‚ΡŒ ΠΏΠΎΠ»Π½ΠΎΠΉ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΈ, Ρ‡Ρ‚ΠΎ Ρƒ ΠΊΠΎΠ³ΠΎ-Ρ‚ΠΎ ΠΈΠ· Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈΠ·-Π·Π° ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ Π½Π΅ΡƒΡ‡Ρ‚Π΅Π½Π½ΠΎΠΉ ΠΌΠ΅Π»ΠΎΡ‡ΠΈ Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ ситуация, ΠΊΠΎΠ³Π΄Π° эта ошибка проявляСтся ΠΊΠ°ΠΊ-Ρ‚ΠΎ ΠΏΠΎ-Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ (ΠΊΠ°ΠΊ ΠΌΡ‹ ΡƒΠΆΠ΅ Π²ΠΈΠ΄Π΅Π»ΠΈ, Π΄Π°ΠΆΠ΅ Π² Ρ€Π°Π·Π½Ρ‹Ρ… вСрсиях Delphi эта ошибка проявляСт сСбя Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-Ρ€Π°Π·Π½ΠΎΠΌΡƒ). Π’ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°Ρ… всС Π³ΠΎΡ€Π°Π·Π΄ΠΎ слоТнСС, ΠΈ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈΠ·-Π·Π° этой ошибки ΠΌΠΎΠΆΠ΅Ρ‚ ΡΡ‚Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΈΠΌ Π½Π΅ΠΎΠΆΠΈΠ΄Π°Π½Π½Ρ‹ΠΌ, Π° проявлСниС этой ошибки β€” Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ Π΄Π°Π»Π΅ΠΊΠΈΠΌ ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ мСста, Π³Π΄Π΅ ΠΎΠ½Π° сдСлана, Ρ‡Ρ‚ΠΎ Π²ΠΏΠΎΡ€Ρƒ Π±ΡƒΠ΄Π΅Ρ‚ "ΠΏΡ€Ρ‹Π³Π°Ρ‚ΡŒ Π²ΠΎΠΊΡ€ΡƒΠ³ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π° с Π±ΡƒΠ±Π½ΠΎΠΌ", изгоняя бСсов. Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΎΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ Π² Ρ‚Π°ΠΊΠΎΠΌ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ, Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π°ΠΊΠΊΡƒΡ€Π°Ρ‚Π½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ со строками (Π° Ρ‚Π°ΠΊΠΆΠ΅ с Π΄Ρ€ΡƒΠ³ΠΈΠΌΠΈ автоматичСски Ρ„ΠΈΠ½Π°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌΠΈ Ρ‚ΠΈΠΏΠ°ΠΌΠΈ: динамичСскими массивами, интСрфСйсами, Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°ΠΌΠΈ), Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ‚ΠΎΡ‚ ΠΊΠΎΠ΄, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ нСявно Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ компилятор, Π½Π΅ оказался Π² Ρ‚ΡƒΠΏΠΈΠΊΠ΅. Π§Π°Ρ‰Π΅ всСго ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‚ ΠΏΡ€ΠΈ ΠΏΠΎΠ±Π°ΠΉΡ‚Π½ΠΎΠΌ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ‚ΠΈΠΏΠ° AnsiString (Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ Π² составС записи) ΠΈΠ»ΠΈ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с Π½Π΅ΠΉ ΠΊΠ°ΠΊ с ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΌ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. Π­Ρ‚ΠΎ Π½Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ AnsiString ΠΊ Π΄Ρ€ΡƒΠ³ΠΈΠΌ указатСлям катСгоричСски нСльзя β€” Ρ€Π°Π½Π΅Π΅ ΠΌΡ‹ ΡƒΠΆΠ΅ Π΄Π΅Π»Π°Π»ΠΈ это, ΠΈ Π²ΠΏΠΎΠ»Π½Π΅ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ. Но, примСняя любой Π½ΠΈΠ·ΠΊΠΎΡƒΡ€ΠΎΠ²Π½Π΅Π²Ρ‹ΠΉ инструмСнт ΠΊ Ρ‚Π°ΠΊΠΈΠΌ строкам, Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ Π΄ΠΎΠ»ΠΆΠ΅Π½ Ρ‡Π΅Ρ‚ΠΊΠΎ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡ‚ΡŒ, ΠΊΠ°ΠΊ это отразится Π½Π° Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠ°Ρ… Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π½ΠΈΠΌΠΈ. Π˜Π½Π°Ρ‡Π΅ β€” Π²ΠΎΡ‚ такая нСпонятная ошибка. 

Π•Ρ‰Π΅ ΠΎΠ΄Π½Π° ситуация, ΠΊΠΎΠ³Π΄Π° записи со строками ΠΌΠΎΠ³ΡƒΡ‚ прСподнСсти ΡΡŽΡ€ΠΏΡ€ΠΈΠ· β€” Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ динамичСский памяти для Π½ΠΈΡ…. Π”ΠΈΠ½Π°ΠΌΠΈΡ‡Π΅ΡΠΊΡƒΡŽ ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ двумя способами: с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρ‹ New ΠΈΠ»ΠΈ GetMem (ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Ρ‚ΡŒ Π΅Π΅ Π½Π°Π΄ΠΎ, соотвСтствСнно, с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Dispose ΠΈΠ»ΠΈ FreeMem). Для записСй, Π½Π΅ содСрТащих строки, эти способы практичСски эквивалСнтны, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈ использовании New объСм выдСляСмой памяти опрСдСляСт компилятор, поэтому New считаСтся Π±ΠΎΠ»Π΅Π΅ бСзопасным Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠΌ. Если ΠΆΠ΅ запись содСрТит строку, Ρ‚ΠΎ эта строка Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π°, ΠΈΠ½Π°Ρ‡Π΅ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π½Π΅ΠΉ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ ошибкС. ΠŸΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° GetMem Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ Π΄Π΅Π»Π°Π΅Ρ‚ с содСрТимым выдСляСмой Сю памяти, ΠΈ строка остаСтся Π½Π΅ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΉ, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ New выполняСт ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ. Π­Ρ‚ΠΎ Π½Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ GetMem Π½Π΅ΠΏΡ€ΠΈΠ³ΠΎΠ΄Π½Π° для выдСлСния памяти для Ρ‚Π°ΠΊΠΎΠΉ записи, просто послС Π²Ρ‹Π·ΠΎΠ²Π° GetMem Π½ΡƒΠΆΠ½ΠΎ Π½Π΅ Π·Π°Π±Ρ‹Ρ‚ΡŒ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΡƒΡŽ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ Initialize, которая ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ строки Π² записи. БоотвСтствСнно, ΠΏΡ€Π΅ΠΆΠ΄Π΅ Ρ‡Π΅ΠΌ ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊΡƒΡŽ запись с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ FreeMem, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Ρƒ Finalize для Ρ„ΠΈΠ½Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ строк. Π­Ρ‚ΠΎ создаСт Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹, Π½Π΅ давая Π½ΠΈΠΊΠ°ΠΊΠΈΡ… прСимущСств, поэтому цСлСсообразнСС всС-Ρ‚Π°ΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ New ΠΈ Dispose.

ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²ΠΎ GetMem ΠΏΠ΅Ρ€Π΅Π΄ New Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Π·Π° ΠΎΠ΄ΠΈΠ½ Π²Ρ‹Π·ΠΎΠ² GetMem ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΠ°ΠΌΡΡ‚ΡŒ сразу для Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… записСй (с ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΠΈΡ… Ρ€ΡƒΡ‡Π½ΠΎΠΉ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ ΠΆΠ΅), Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ New выдСляСт ΠΏΠ°ΠΌΡΡ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для ΠΎΠ΄Π½ΠΎΠ³ΠΎ экзСмпляра записи. Но с появлСниСм Π² языкС динамичСских массивов это прСимущСство Ρ‚ΠΎΠΆΠ΅ пСрСстало Π±Ρ‹Ρ‚ΡŒ особо ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΌ. ΠŸΡ€ΠΎΡ‰Π΅ ΠΎΠ±ΡŠΡΠ²ΠΈΡ‚ΡŒ динамичСский массив ΠΈΠ· записСй ΠΈ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ‚Ρ€Π΅Π±ΡƒΠ΅ΠΌΠΎΠ΅ число элСмСнтов Π² Π½Π΅ΠΌ β€” компилятор сам позаботится ΠΎΠ± ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Ρ‚Π°ΠΊΠΈΡ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ…. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΌΡ‹ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ ΠΎΡ‚ΠΊΠ°Π·Π°Ρ‚ΡŒΡΡ ΠΎΡ‚ GetMem ΠΏΡ€ΠΈ Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠΈ памяти ΠΏΠΎΠ΄ записи со строками, Π° Ссли ΡƒΠΆ Π²Ρ‹ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΠ»ΠΈΡΡŒ с ситуациСй, ΠΊΠΎΠ³Π΄Π° Π±Π΅Π· этого совсСм Π½ΠΈΠΊΠ°ΠΊ, Π½Π΅ Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Initialize ΠΈ Finalize.