Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   FreeMem D2009 und FastMM (https://www.delphipraxis.net/160175-freemem-d2009-und-fastmm.html)

EWeiss 1. Mai 2011 04:34

FreeMem D2009 und FastMM
 
Was läuft hier schief das ich ein riesen log von FastMM bekomme?
Delphi-Quellcode:
function ListGetText(hList: HWND; Item: Integer): PWideChar;
var
  sItem: PWideChar;
  nLEN : Integer;
begin
    if Item > 0 then
       dec(Item);

    nLEN := SendMessage(hList, LB_GETTEXTLEN, Item, 0) + 1;
    sItem := AllocMem(nLEN);
    SendMessage(hList, LB_GETTEXT, Item, integer(sItem));

    Result := sItem;
    FreeMem(sItem, nLEN);

end;
Ist mir unbegreiflich.
Habe exakt 108 Zeichen und am Mauszeiger (ToolTip) wird der exakte pfad bis jpg angezeigt.
FastMM zeigt aber mehr zeichen hinter JPG an als ich beim Debuggen zu sehen bekomme.
Sollte eigentlich korrekt sein.

gruss

FredlFesl 1. Mai 2011 07:34

AW: FreeMem D2009 und FastMM
 
Du gibst sItem frei, obwohl es noch gebraucht wird.
Delphi-Quellcode:
function ListGetText(hList: HWND; Item: Integer): PWideChar;
...
begin
    ...
    Result := sItem;
    FreeMem(sItem, nLEN); // <<<--------- Das kann nicht gut gehen

end;
Gib einen WideString zurück.

himitsu 1. Mai 2011 08:12

AW: FreeMem D2009 und FastMM
 
Am Einfachsten gleich direkt in den WideString reinschreiben.
Delphi-Quellcode:
function ListGetText(hList: HWND; Item: Integer): WideString;
begin
    if Item > 0 then
       dec(Item);
    SetLength(Result, SendMessage(hList, LB_GETTEXTLEN, Item, 0));
    SendMessage(hList, LB_GETTEXT, Item, LPARAM(Result));
end;

EWeiss 1. Mai 2011 09:12

AW: FreeMem D2009 und FastMM
 
Zitat:

Zitat von himitsu (Beitrag 1097992)
Am Einfachsten gleich direkt in den WideString reinschreiben.
Delphi-Quellcode:
function ListGetText(hList: HWND; Item: Integer): WideString;
begin
    if Item > 0 then
       dec(Item);
    SetLength(Result, SendMessage(hList, LB_GETTEXTLEN, Item, 0));
    SendMessage(hList, LB_GETTEXT, Item, LPARAM(Result));
end;

Kein Memory allozieren ?
Und Freigeben?

Denn AllocMem benötigt einen pointer.

PS:
Und damit wäre es auch nicht getan denn CopyFile erwartet ein PWideChar!
Delphi-Quellcode:
          Img := SKAERO_CreateImageFromFile(ListGetText(hList, ListItem));
          if Img <> 0 then
          begin
            hImg := cardinal(SKAERO_GetProperty(WinHandle, FORM_Center));
            SKAERO_DisposeImage(hImg);
            CopyFile(ListGetText(hList, ListItem), PWideChar(
              SKAERO_CENTERFORM), False);
            SKAERO_SetProperty(WinHandle, FORM_Center, Img);
            ResizeWindow(WinHandle, 1);
          end;

Das war auch der Grund das ich über PWideChar gegangen bin
um das unnötige hin und her konvertieren zu vermeiden.

Der Fehler ist auf jedenfall weg ..
Danke.

gruss

jbg 1. Mai 2011 10:59

AW: FreeMem D2009 und FastMM
 
Noch als Anmerkung:
Zitat:

Zitat von EWeiss (Beitrag 1097983)
sItem := AllocMem(nLEN);

Du weißt aber schon, dass ein PWideChar aus 2 Byte-Zeichen besteht, also nLEN*2 Bytes notwendig sind. Zudem ist in nLEN das abschließende #0 nicht enthalten, also sind (nLEN+1)*2 Bytes notwendig.

EWeiss 1. Mai 2011 11:32

AW: FreeMem D2009 und FastMM
 
Zitat:

Zitat von jbg (Beitrag 1098020)
Noch als Anmerkung:
Zitat:

Zitat von EWeiss (Beitrag 1097983)
sItem := AllocMem(nLEN);

Du weißt aber schon, dass ein PWideChar aus 2 Byte-Zeichen besteht, also nLEN*2 Bytes notwendig sind. Zudem ist in nLEN das abschließende #0 nicht enthalten, also sind (nLEN+1)*2 Bytes notwendig.

Ehrlich gesagt Nein.
Aber jetzt bin ich etwas schlauer.

gruss

himitsu 1. Mai 2011 15:11

AW: FreeMem D2009 und FastMM
 
CopyFile wäre eh falsch, denn dieses will einen PChar.
CopyFileW wäre für PWideChar.


Mit PWideChar(s) kann man einen PWideChar erstellen, welcher auf einen WideString zeigt. (einfach direkt beim Aufruf der Funktion casten)

PS: PChar, PAnsiChar und PWideChar sind nur Zeiger, welcher auf Speicherbereiche zeigen ... darum auch P ie Pointer.
Wenn deine Funktion also PWideChar zurücliefern soll, dann darfst du den Speicher also nicht freigeben (nicht an dieser Stelle, sondern erst später)


Warum um Himmels Willen prädige ich ständig umsonst, daß man Typen nicht vermischen soll?
AnsiString, PAnsiChar, AnsiChar und AnsiAPI (ala CopyFileA)
WideString/UnicodeString, PWideChar, WideChar und UnicodeAPI (ala CopyFileW)
ODER
String, PChar, Char und dynamischer API (ala CopyFile), welches sich an den jeweiligen Compiler anpaßt, bzw. welches an den Compiler angepaßt ist.

FredlFesl 1. Mai 2011 16:59

AW: FreeMem D2009 und FastMM
 
Zitat:

Zitat von EWeiss (Beitrag 1098000)
Zitat:

Zitat von himitsu (Beitrag 1097992)
Delphi-Quellcode:
function ListGetText(hList: HWND; Item: Integer): WideString;
begin
    if Item > 0 then
       dec(Item);
    SetLength(Result, SendMessage(hList, LB_GETTEXTLEN, Item, 0));
    SendMessage(hList, LB_GETTEXT, Item, LPARAM(Result));
end;

Kein Memory allozieren ?
Und Freigeben?

SetLength allokiert den Speicher. Die Freigabe erfolgt über die Referenzzählung der Strings.

EWeiss 1. Mai 2011 17:58

AW: FreeMem D2009 und FastMM
 
Zitat:

Zitat von himitsu (Beitrag 1098081)
CopyFile wäre eh falsch, denn dieses will einen PChar.
CopyFileW wäre für PWideChar.

Und genau das ist der Müll den Embagardo oder wer auch immer verzapft hat.

Siehe!
function CopyFile; external kernel32 name 'CopyFileW'; // << Warum dieser Schwachsinn.
function CopyFileW; external kernel32 name 'CopyFileW';

Wie soll ein normal Sterblicher damit zurecht kommen.
Schießlich esse ich keinen Apfel wenn ich eine Apfelsine gekauft habe. Oder?
Wenn ich schon nur mit Unicode Arbeiten darf dann benötige ich diese Funktion nicht das verwirrt nur.
EntwderOder.

Zitat:

Warum um Himmels Willen prädige ich ständig umsonst, daß man Typen nicht vermischen soll?
AnsiString, PAnsiChar, AnsiChar und AnsiAPI (ala CopyFileA)
WideString/UnicodeString, PWideChar, WideChar und UnicodeAPI (ala CopyFileW)
ODER
String, PChar, Char und dynamischer API (ala CopyFile), welches sich an den jeweiligen Compiler anpaßt, bzw. welches an den Compiler angepaßt ist.
Das sind die feinen Unterschied zwischen einem Programmierer (Studierten) und einen Hobby Programmierer. ;)

Zitat:

prädige = predige!
etwas predigen gesprochen... jemandem immer wieder sagen, wie er sich verhalten soll. ;)

Danke.

gruss

himitsu 1. Mai 2011 18:14

AW: FreeMem D2009 und FastMM
 
Zitat:

Zitat von EWeiss (Beitrag 1098109)
Und genau das ist der Müll den Embagardo oder wer auch immer verzapft hat.

Das ist doch richtig so?

Die WinAPI kennt nut CopyFileA und CopyFileW.
Dieses ist beides in Delphi implementiert
und zusätzlich noch das CopyFile, welches an den "StandardString" des verwendeten Compilers angepaßt ist.
PS: Das ist auch in den C-Headern so.

Char, String, PChar und die APIs ala CopyFile sind Weiterleitungen, welche an den Compiler angepaßt sind.


Wenn du also immer nur String, PChar und die dynamischen APIs nutzt, dann paßt sich dieses jeweils an den Compiler an.

Bis Delphi 2007 also Ansi und ab 2009 Unicode.
Alles andere ist fest uns somit überall gleich.

Ersteres nutzt man, wenn man den "aktuellen"Standard möchte
und Letzteres nutzt man, wenn man unbedingt auf ein bestimmtes Format angewiesen ist.


Genau das Gleiche ist mit dem Integer und LongInt,
wobei hier wirklich jemand mist gebaut hat und urplötzlich, beim Umstieg von 32 auf 64 Bit den Integer eingefrohren hat. :wall:


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:02 Uhr.
Seite 1 von 2  1 2      

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