Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   EInvalidPointer, warum? (https://www.delphipraxis.net/202462-einvalidpointer-warum.html)

DualCoreCpu 6. Nov 2019 19:09

EInvalidPointer, warum?
 
Hallo,

ich habe i etwa folgenden Code:

Delphi-Quellcode:
type
  TMenuNameStr = array[0..31] of Ansichar;
  TProgNameStr = array[0..255] of AnsiChar;
  TDirNameStr = array[0..255] of AnsiChar;
  TCfgNameStr = array[0..29] of Ansichar;
  TOptionsStr = array[0..127] of Ansichar;
  TRegisteredCommand = class(TObject)
  private
    FMenuName: TMenuNameStr;
    FProgName: TProgNameStr;
    FDirName: TDirNameStr;
    FOptions: TOptionsStr;
    FCfgFile: TCfgNameStr;
    function GetCfgFile: ShortString;
    function GetDirName: ShortString;
    function GetMenuName: ShortString;
    function GetOptions: ShortString;
    function GetProgName: ShortString;
    procedure SetCfgFile(const Value: ShortString);
    procedure SetDirName(const Value: ShortString);
    procedure SetMenuName(const Value: ShortString);
    procedure SetOptions(const Value: ShortString);
    procedure SetProgName(const Value: ShortString);
  public
   {
    constructor Create;
    destructor Destroy; override;
   }
    constructor Create;
    property MenuName: ShortString read GetMenuName write SetMenuName;
    property ProgName: ShortString read GetProgName write SetProgName;
    property DirName: ShortString read GetDirName write SetDirName;
    property Options: ShortString read GetOptions write SetOptions;
    property CfgFile: ShortString read GetCfgFile write SetCfgFile;
  end;

  TCommandsList = class(TObjectList)
    property Command: TRegisteredCommand read GetCommand write SetCommand;
  end;
Im Hauptprogramm habe ich dann in der MainForm die Felder FCommands: TCommandsList und FCmd: TRegisteredCommand. Das erstere steht für die Kommandoliste, das zweite für ein einzenes Kommando.

Das aktuelle aufzurufende Kommando wähle ich aus einer Liste aus, die mir auf Menüauswahl von einem Dialog bereitgestellt wird. Dazu brauche ich dann mindestens den Zeiger FCmd. FCommands nimmt die gesamte Liste aller Kommandos auf.

Wenn ich nun im Hauptprogramm an FCmd ein Kommando vom dafür vorgesehenen Dialog zuweise und beim Beenden diesen Zeiger freigeben will, erhalte ich die ungültige Zeigeroperation ( EInvalidPointer ).

Den Konstruktor vorher aufrufen führt nicht zum Erfolg.

Im Hauptprogramm beende ich so:

Delphi-Quellcode:
    if (CmdChoose.Cmd <> NIL) and (CmdChoose.Cmd.MenuName <> '') then
    begin
      case CmdChoose.ItemIndex of
        0: begin
             if FCmd <> nil then
             begin
               FCmd.MenuName := CmdChoose.Compiler.MenuName;
               FCmd.DirName := CmdChoose.Compiler.DirName;
               FCmd.ProgName := CmdChoose.Compiler.ProgName;
               FCmd.CfgFile := CmdChoose.Compiler.CfgFile;
               FCmd.Options := CmdChoose.Compiler.Options;
             end
             else
             begin
               FCmd := TCmd.Create;
               FCmd.MenuName := CmdChoose.Compiler.MenuName;
               FCmd.DirName := CmdChoose.Compiler.DirName;
               FCmd.ProgName := CmdChoose.Compiler.ProgName;
               FCmd.CfgFile := CmdChoose.Compiler.CfgFile;
               FCmd.Options := CmdChoose.Compiler.Options;
             end;
             FCmd.OptionsDialog := TFirstCmdOptDlg.Create(self);
        end;
        1: begin
            FCmd := CmdChoose.Cmd;
            dlg := TSecondCmdOptDialog.Create(self);
            FCmd.OptionsDialog := dlg;
        end;
      end;
In einer FormDestroy Methode im Hauptprogramm gebe ich dann die Zeigerfelder FCommands und FCmd frei und da erhalte ich die ungültige Zeigeroperation ( EInvalidPointer ).

Warum?

Wenn ich kein Kommando auswähle, kann ich das Programm ohne Fehler beenden.

hoika 6. Nov 2019 19:52

AW: EInvalidPointer, warum?
 
Hallo,

Fall 1
FCmd := TCmd.Create;
FCmd wird erzeugt

Fall 2
FCmd := CmdChoose.Cmd;
FCmd wird nicht erzeugt!

gebe FCmd frei
Fall 2
CmdChoose wird doch auch freigegeben, oder ?
Damit zeigt FCmd auf einen bereits freigegebenen Pointer -> Puff

DualCoreCpu 6. Nov 2019 20:40

AW: EInvalidPointer, warum?
 
Juhuuuu, danke, das wer es. Ich hatte einne FormCloseQuery Methode, ich der ich die Zeiger frei gegeben habe, dann aber in FormDestroy nochmals. Bingo! :wall:

hoika 7. Nov 2019 07:36

AW: EInvalidPointer, warum?
 
Hallo,
kann man ja auch so machen,
indem man FreeAndNil benutzt.

var
p: Pointer;

FreeAndNil(P);

// dum di dum

FreeAndNil(P); // ergibt keine Fehler


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:44 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz