Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi BoolToStr wirft Memcheck Exception. (https://www.delphipraxis.net/108779-booltostr-wirft-memcheck-exception.html)

pertzschc 19. Feb 2008 14:04


BoolToStr wirft Memcheck Exception.
 
Hallo zusammen,

ich habe ein Projekt, welches ich gerade mit Memcheck auf Leaks überprüfe. Dabei meckert Memcheck folgende Codezeile an:

Delphi-Quellcode:
unit uProject.pas
// schreibe daten des projektes
...
319: ini.WriteString(cIniSectionProject, project_usernumberwithzero, BoolToStr(aTestProject.NumberWithZero, true));
...
Auszug aus dem Memcheck.log:

Size: 14
2 Occurences
call stack - 0 : (no debug info) Find error: 0000000E
call stack - 1 : Module sysutils.pas Routine @Sysutils@BoolToStr Line 4720 Find error: 0040A576
call stack - 2 : Module uProject.pas Routine @Uproject@SaveProjectDataToFile Line 319 Find error: 0054C3F0

Was läuft hier in @Sysutils@BoolToStr für Memcheck falsch ab?

Gruß,
Christoph

mkinzler 19. Feb 2008 14:10

Re: BoolToStr wirft Memcheck Exception.
 
Was steht in aTestProject.NumberWithZero?

pertzschc 19. Feb 2008 14:16

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von mkinzler
Was steht in aTestProject.NumberWithZero?

Das ist eine public Property vom Typ boolean:

Delphi-Quellcode:
fNumberWithZero: boolean; // sollen nach dem prefix der nummernbereich mit nullen aufgefüllt werden?
...
property NumberWithZero: boolean read fNumberWithZero write fNumberWithZero;
...
constructor TTestProject.Create;
begin
  // rufe vater auf
  inherited Create;
  // eigene daten inits
  fNumberWithZero:=true;
end;

mkinzler 19. Feb 2008 14:17

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Das ist eine public Property
Das dürfte das Problem sein.

pertzschc 19. Feb 2008 14:25

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von mkinzler
Zitat:

Das ist eine public Property
Das dürfte das Problem sein.

Kannst Du es mir bitte näher erklären? Die Property ist vom typ boolean, was passiert da in BoolToStr() anderes als sonst?
Vielen Dank,
Christoph

pertzschc 6. Aug 2008 17:05

Re: BoolToStr wirft Memcheck Exception.
 
Hat keiner mehr eine Idee, was an der Property nun so falsch ist? (*Push*)

Gruß,
Chritoph

Neutral General 6. Aug 2008 17:12

Re: BoolToStr wirft Memcheck Exception.
 
Hi,

Also an den Properties kann es eigentlich nicht liegen, denn das hier funktioniert:

Delphi-Quellcode:
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    FVS: Boolean;
    { Private declarations }
  public
    property Test: Boolean read FVS write FVS;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Test := false;
  Caption := BoolToStr(Test,true);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Test := true;
end;
Schau lieber mal dort nach:

Zitat:

call stack - 2 : Module uProject.pas Routine @Uproject@SaveProjectDataToFile Line 319 Find error: 0054C3F0
Ich würde glatt behaupten, dass du dich da irgendwie verwurschtelt hast (vlt. auch mit Pointern) und es dann erst anschließend kracht (anschließend ist zufälligerweise BoolToStr).

Gruß
Neutral General

pertzschc 6. Aug 2008 17:17

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von Neutral General
Schau lieber mal dort nach:

Zitat:

call stack - 2 : Module uProject.pas Routine @Uproject@SaveProjectDataToFile Line 319 Find error: 0054C3F0
Ich würde glatt behaupten, dass du dich da irgendwie verwurschtelt hast (vlt. auch mit Pointern) und es dann erst anschließend kracht (anschließend ist zufälligerweise BoolToStr).

Schau mal in meinen 1. Beitrag, da ist die Zeile 319 enthalten. Es kracht auch nicht in der Programmausführung, sondern Memcheck meldet ein Speicherleck im Zusammenhang mit BoolToStr() - Aufruf.

Hast Du noch eine Idee?

Gruß,
Christoph

RWarnecke 6. Aug 2008 17:18

Re: BoolToStr wirft Memcheck Exception.
 
Mal eine Frage, warum der Umweg über die Public-Property ? Ich würde statt
Delphi-Quellcode:
BoolToStr(aTestProject.NumberWithZero, true)
dieses hier schreiben
Delphi-Quellcode:
BoolToStr(fNumberWithZero, true)

pertzschc 6. Aug 2008 17:23

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von RWarnecke
Mal eine Frage, warum der Umweg über die Public-Property ? Ich würde statt
Delphi-Quellcode:
BoolToStr(aTestProject.NumberWithZero, true)
dieses hier schreiben
Delphi-Quellcode:
BoolToStr(fNumberWithZero, true)

Ganz einfach, der Pointer auf das Projekt wird in die statische function() mit reingegeben.
Delphi-Quellcode:
function SaveProjectDataToFile(aTestProject: TTestProject): boolean;
Daher der Zugriff auf alle public properties des Objektes für das Speichern. Hältst Du das für falsch?
Gruß,
Christoph

RWarnecke 6. Aug 2008 18:36

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von pertzschc
Daher der Zugriff auf alle public properties des Objektes für das Speichern. Hältst Du das für falsch?
Gruß,
Christoph

Ich benutze immer lokale Variablen und keine globalen Variablen. Es geht da bei um das Freigeben der Klasse. Ich habe das gleiche Problem auch noch in einer meiner Klassen. Ich habe im Interface-Teil eine Variable deklariert. Diese Variable erstelle ich im constructor und gebe Sie wieder im Destructor frei. Da habe ich das gleiche Problem. Ich habe schon die ersten Anfänge gemacht und alles auf die private/protected Variablen umzustellen und meine Memory-Leaks verschwinden wie von Zauberhand.

Funktioniert es denn, wenn Du es abänderst, wie ich es geschrieben habe ?

Edit:
Deine Proberty schreibt und liest doch den Wert fNumberWithZero, warum sollte es nicht funktionieren ?

pertzschc 6. Aug 2008 18:50

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von RWarnecke
Deine Proberty schreibt und liest doch den Wert fNumberWithZero, warum sollte es nicht funktionieren ?

Nein, die function ist eine in der Unit deklarierte globale Funktion. Sie bekommt als Argument ein Objekt, welches ein TestProject darstellt. Dieses Objekt hat public properties, an denen jeweils eine Set/Get-Methode hängt.
Diese Eigenschaften des Objektes werden dann in der Save-function als Werte in eine INI-Datei geschrieben. Daher ist kein Zugriff innerhalb der function auf private Eigenschaften des übergebenen Objektes möglich. Dann müsste ich die fAttribute public machen und auf Set/Get-Methoden der Properties verzichten. Das macht für mich keinen Sinn wenn ich hier kapseln möchte. Hilft diese Erklärung zum besseren Verstehen?

Delphi-Quellcode:
type
  TTestProject = class(TObject)
  private
    { Private declarations }
    fName: string;                // name des projektes
    fNumberWithZero: boolean; // sollen nach dem prefix der nummernbereich mit nullen aufgefüllt werden?
    ...
    // methoden
    procedure Set_NumberWithZero(aNumberWithZero: boolean);
    function Get_NumberWithZero: boolean;
    ...
  public
    { Public declarations }
    // properties
    property Id: string read Get_IdStr;
    property Name: string read fName write fName;
    property NumberWithZero: boolean read Get_NumberWithZero write Set_NumberWithZero;
    ...
    // konstruktor etc...
    constructor Create; overload;
    destructor Destroy; override;
  end;
Gruß,
Christoph

RWarnecke 6. Aug 2008 19:22

Re: BoolToStr wirft Memcheck Exception.
 
Irgendwie verstehe ich das nicht ganz. Im Beitrag 3 haste noch diese Zeile geschrieben :
Delphi-Quellcode:
property NumberWithZero: boolean read fNumberWithZero write fNumberWithZero;
Jetzt soll die Zeile so heissen :
Delphi-Quellcode:
property NumberWithZero: boolean read Get_NumberWithZero write Set_NumberWithZero;
Was ist denn nun richtig ?

Ein Memory Leak ist ja nichts anderes, Du hast Speicher reserviert und gibst diesen nicht wieder frei. Dieses muss ja innerhalb der Ermittlung von der Property NumberWithZero passieren. Zum Beispiel :
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  numbers : TStringList;
begin
  numbers := TStringList.Create;
  numbers.Add('Testeintrag 1');
end;
Bei dieser Procedure wird auch ein Memory Leak angezeigt für die Stringliste.


Edit:
Hast Du schonmal mit EurekaLog das ganze untersucht. Eurekalog zeigt Dir den ganzen Weg auf, von da wo es auftritt, bis zum Ursprung.

Bernhard Geyer 6. Aug 2008 19:46

Re: BoolToStr wirft Memcheck Exception.
 
Hast du evtl. Compileroptimierungen an? Darauf reagiert AFAIK MemCheck allergisch.
Ich würde eh FastMM verwenden. Vorteile zu MemCheck:

- Zusätzlich besserer Memory Manager
- Wird noch aktiv weiterentwickelt.

pertzschc 6. Aug 2008 20:25

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von RWarnecke
Irgendwie verstehe ich das nicht ganz. Im Beitrag 3 haste noch diese Zeile geschrieben :
Delphi-Quellcode:
property NumberWithZero: boolean read fNumberWithZero write fNumberWithZero;
Jetzt soll die Zeile so heissen :
Delphi-Quellcode:
property NumberWithZero: boolean read Get_NumberWithZero write Set_NumberWithZero;
Was ist denn nun richtig ?

Beides ist richtig. Die Set/Get-Methoden sind die Weiterentwicklung, anfangs war es noch ein direkter read/write auf das private Attribut.

Zitat:

Zitat von RWarnecke
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  numbers : TStringList;
begin
  numbers := TStringList.Create;
  numbers.Add('Testeintrag 1');
end;
Bei dieser Procedure wird auch ein Memory Leak angezeigt für die Stringliste.

Das Beispiel passt für mein Problem nicht ganz. Bei mir würde ich jetzt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  test : boolean;
begin
  test := BoolToStr(Sender.IsChild, true);
end;
als Code haben. Dann meckert Memcheck in der Zeile:
Delphi-Quellcode:
  test := BoolToStr(Sender.IsChild, true);
Zitat:

Zitat von RWarnecke
Hast Du schonmal mit EurekaLog das ganze untersucht. Eurekalog zeigt Dir den ganzen Weg auf, von da wo es auftritt, bis zum Ursprung.

Danke für den Tipp, werde ich mir mal anschauen.

pertzschc 6. Aug 2008 20:27

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von Bernhard Geyer
Hast du evtl. Compileroptimierungen an? Darauf reagiert AFAIK MemCheck allergisch.
Ich würde eh FastMM verwenden. Vorteile zu MemCheck:

- Zusätzlich besserer Memory Manager
- Wird noch aktiv weiterentwickelt.

Die Optimierungen sind aus, wenn im dpr-File Memcheck eingebunden ist.

Danke für den Tipp mit FastMM. Funktioniert das auch mit Delphi 7 und wo kann ich ein Tutorial dazu finden?

Gruß,
Christoph

RWarnecke 6. Aug 2008 20:34

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von pertzschc
Das Beispiel passt für mein Problem nicht ganz. Bei mir würde ich jetzt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  test : boolean;
begin
  test := BoolToStr(Sender.IsChild, true);
end;
als Code haben. Dann meckert Memcheck in der Zeile:
Delphi-Quellcode:
  test := BoolToStr(Sender.IsChild, true);

Ich glaube noch nicht ganz, das es an der Funktion BoolToStr liegt. Deshalb würde ich mich da nicht ganz drauf fixieren. Zu Hier im Forum suchenFastMM findest Du hier einige Einträge im Forum.

jim_raynor 6. Aug 2008 21:52

Re: BoolToStr wirft Memcheck Exception.
 
Zitat:

Zitat von pertzschc
Danke für den Tipp mit FastMM. Funktioniert das auch mit Delphi 7 und wo kann ich ein Tutorial dazu finden?

Ja, funktioniert viel besser als MemCheck.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:41 Uhr.

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