Если на один объект есть несколько ссылок, то освобождение его с помощью одной ссылки ничего не делает с другими.
В смысле по другим ссылкам к нему по прежнему можно обращаться и во многих случаях результат будет, как будто никто его и не освобождал.
Специально написал простенький тест
pas
- Код: Выделить всё
- unit UfmTestFreeError;
 {$MODE Delphi}
 {$OBJECTCHECKS+}
 interface
 uses
 LCLIntf, LCLType, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, Buttons, MaskEdit;
 type
 TSimpleInt = class
 public
 Value: integer;
 constructor Init(V: integer);
 destructor Destroy; override;
 end;
 { TfmTestFreeError }
 TfmTestFreeError = class(TForm)
 bnCreate: TBitBtn;
 edResult: TEdit;
 bnRead: TBitBtn;
 Label1: TLabel;
 Label2: TLabel;
 medSource: TMaskEdit;
 bnFree: TBitBtn;
 procedure bnCreateClick(Sender: TObject);
 procedure bnReadClick(Sender: TObject);
 procedure bnFreeClick(Sender: TObject);
 private
 { Private declarations }
 SimpleInt: TSimpleInt;
 SimpleRef: TSimpleInt;
 public
 { Public declarations }
 end;
 var
 fmTestFreeError: TfmTestFreeError;
 implementation
 {$R *.lfm}
 { TSimpleInt }
 constructor TSimpleInt.Init(V: integer);
 begin
 inherited Create;
 Value := V;
 end;
 destructor TSimpleInt.Destroy;
 begin
 inherited;
 //Self := nil;
 end;
 procedure TfmTestFreeError.bnReadClick(Sender: TObject);
 begin
 edResult.Text := IntToStr(SimpleRef.Value);
 end;
 procedure TfmTestFreeError.bnCreateClick(Sender: TObject);
 begin
 SimpleInt := TSimpleInt.Init(StrToInt(medSource.Text));
 SimpleRef := SimpleInt;
 end;
 procedure TfmTestFreeError.bnFreeClick(Sender: TObject);
 begin
 FreeAndNil(SimpleInt);
 end;
 end.
lfm
- Код: Выделить всё
- object fmTestFreeError: TfmTestFreeError
 Left = 436
 Height = 147
 Top = 200
 Width = 528
 Caption = 'Test Free Error'
 ClientHeight = 147
 ClientWidth = 528
 Color = clBtnFace
 Font.Color = clWindowText
 Font.Height = -11
 Font.Name = 'MS Sans Serif'
 LCLVersion = '1.6.2.0'
 object edResult: TEdit
 Left = 64
 Height = 21
 Top = 48
 Width = 121
 TabOrder = 0
 end
 object bnRead: TBitBtn
 Left = 312
 Height = 25
 Top = 56
 Width = 121
 Caption = 'Read'
 OnClick = bnReadClick
 TabOrder = 1
 end
 object medSource: TMaskEdit
 Left = 64
 Height = 21
 Top = 16
 Width = 120
 CharCase = ecNormal
 MaxLength = 5
 TabOrder = 2
 EditMask = '!99999;1;_'
 Text = ' '
 SpaceChar = '_'
 end
 object bnFree: TBitBtn
 Left = 312
 Height = 25
 Top = 96
 Width = 121
 Caption = 'Free'
 OnClick = bnFreeClick
 TabOrder = 3
 end
 object Label1: TLabel
 Left = 8
 Height = 13
 Top = 20
 Width = 32
 Caption = 'Число'
 ParentColor = False
 end
 object Label2: TLabel
 Left = 8
 Height = 13
 Top = 56
 Width = 52
 Caption = 'Результат'
 ParentColor = False
 end
 object bnCreate: TBitBtn
 Left = 312
 Height = 25
 Top = 16
 Width = 121
 Caption = 'Create'
 OnClick = bnCreateClick
 TabOrder = 4
 end
 end
Кнопкой Create создается объект и на него делается вторая ссылка.
Кнопкой Free первая ссылка освобождается
Кнопкой Read выводится содержимое объекта по второй ссылке. Легко убедится, что Read прекрасно работает после Free.
На разных платформах и в среде Delphi.
Меня удивляет не столько наличие проблемы, сколько отсутствие даже ее обсуждения.
Со своей стороны хочу предложить, чтобы при освобождении объекта , обнулялся его указатель self. Я попробовал это сделать самостоятельно, но при этой операции программа иногда падает, а иногда все равно все работает (правда, содержимое портится, но это несущественно).
Ну и понятно, что это должно делаться на системном уровне.







