![]() |
Problem mit Speicherfreigabe bei dynamischen Array als function-Übergabe
Hallo,
wie in diesem ![]() Das klappt auch soweit ganz gut. Ich hab das in einem Testprojekt getestet und hab jetzt für mein eigentliches Projekt eine function erstellt, die aber alles in einem dynamischen Array speichert.
Delphi-Quellcode:
Mein Problem ist, dass sich FastMM am Ende vom Programm fast überschlägt weil Speicher nicht freigegeben worden ist.
TAdapter_Rec = packed record
AdapterName : String; FriendlyName: String; DHCP_Enabled: Boolean; IP_Address : String; Subnetmask : String; Gateway : String; end; TAdapter_Array = array of TAdapter_Rec; function NetzwerkInfos_auslesen(var Liste: TAdapter_Array; out ErrorCode: Integer): Boolean; var i : Byte; pAdapterList : PIP_ADAPTER_INFO; pAdapterAddresses : PIP_ADAPTER_ADDRESSES; LenAdapter_List : DWORD; LenAdapter_Address: DWORD; ErrorCode_List : DWORD; ErrorCode_Address : DWORD; AdapterName : String; begin //Rückgabewerte vordefinieren Result := false; ErrorCode := 0; //Variable initialisieren i := 0; LenAdapter_List := 0; LenAdapter_Address := 0; ErrorCode_List := 0; ErrorCode_Address := 0; pAdapterList := nil; // Alles auf 0 ==> Benötigte Buffergrösse ermitteln //AdapterList ErrorCode_List := GetAdaptersInfo(pAdapterList, LenAdapter_List); If ErrorCode_List <> ERROR_BUFFER_OVERFLOW then begin ErrorCode := ErrorCode_List; exit; end; //Länge auslesen, bei Fehler Fehlercode setzen und Procedure beenden ErrorCode_Address := GetAdaptersAddresses(0, 0, nil, nil, @LenAdapter_Address); If ErrorCode_Address <> ERROR_BUFFER_OVERFLOW then begin ErrorCode := ErrorCode_Address; exit; end; //Speicher anfordern pAdapterList := AllocMem(LenAdapter_List); pAdapterAddresses := AllocMem(LenAdapter_Address); try //AdapterList auslesen ErrorCode_List := GetAdaptersInfo(pAdapterList, LenAdapter_List); //wenn das Auslesen der Adapter-List fehlgeschlagen hat, dann Fehlercode //setzen und Procedure beenden If ErrorCode_List <> ERROR_SUCCESS then begin ErrorCode := ErrorCode_List; exit; end; //AdapterAddresses auslesen ErrorCode_Address := GetAdaptersAddresses(0, 0, nil, pAdapterAddresses, @LenAdapter_Address); //wenn das Auslesen der Adapter-Addresses fehlgeschlagen hat, dann Fehlercode //setzen und Procedure beenden If ErrorCode_Address <> ERROR_SUCCESS then begin ErrorCode := ErrorCode_Address; exit; end; while Assigned(pAdapterList) do begin //Variable erhöhen inc(i); //Anzahl der Einträge erhöhen SetLength(Liste, i); Liste[Pred(i)].AdapterName := String(pAdapterList.AdapterName); Liste[Pred(i)].DHCP_Enabled := Boolean(pAdapterList.DhcpEnabled); Liste[Pred(i)].IP_Address := String(pAdapterList.IpAddressList.IpAddress.S); Liste[Pred(i)].Subnetmask := String(pAdapterList.IpAddressList.IpMask.S); Liste[Pred(i)].Gateway := String(pAdapterList.GatewayList.IpAddress.S); pAdapterList := pAdapterList.Next; end; while Assigned(pAdapterAddresses) do begin for i := low(Liste) to high(Liste) do If Liste[i].AdapterName = String(pAdapterAddresses.AdapterName) then begin Liste[i].FriendlyName := String(pAdapterAddresses.FriendlyName); break; end; pAdapterAddresses := pAdapterAddresses.Next; end; //Rückgabewert Result := true; finally // FreeMem(pAdapterList); FreeMem(pAdapterAddresses); end; end; Nun vermute ich, dass es mit dem SetLength zusammenhängt - ich fordere Speicher an, gib ihn aber nicht mehr frei. Ich hab schon versucht, dort, wo ich die function aufrufe, am Ende die Variabe für "Liste" freizugeben (
Delphi-Quellcode:
), aber auch das bringt nicht den gewünschten Erfolg.
SetLength(Variable, 0)
Wie gib ich denn nun sauber den Speicher wieder frei? |
AW: Problem mit Speicherfreigabe bei dynamischen Array als function-Übergabe
Zitat:
Und bei pAdapterList isses das Selbe. Aber überschlagen ist bei diesen 2 größere Speicherblöcken wohl etwas übertrieben. :gruebel: |
AW: Problem mit Speicherfreigabe bei dynamischen Array als function-Übergabe
Zitat:
Der Speicher wird ja angefordert:
Delphi-Quellcode:
und der Wert wird über FreeMem wieder freigegeben:
//Speicher anfordern
pAdapterList := AllocMem(LenAdapter_List); pAdapterAddresses := AllocMem(LenAdapter_Address);
Delphi-Quellcode:
Oder meinst du ich muss mir den Originalwert von pAdapterList und pAdapterAddresses speichern um diese dann dem FreeMem zu übergeben?
finally
// FreeMem(pAdapterList); FreeMem(pAdapterAddresses); end; (was jetzt Sinn machen würde) [edit] Also wenn ich mir den Originalwert speichere und diesen dann freigebe, dann gibt FreeMem Ruhe! - Danke für den Tip!! |
AW: Problem mit Speicherfreigabe bei dynamischen Array als function-Übergabe
[QUOTE=himitsu;1188770]
Zitat:
Himitsu editiert seine Beiträge immer so langsam - da kann es schon mal passieren, dass man doppelpostet :mrgreen: |
AW: Problem mit Speicherfreigabe bei dynamischen Array als function-Übergabe
Rate mal, was in der Zwischenzeit mit dem Zeiger passiert, bei
Delphi-Quellcode:
?
pAdapterAddresses := pAdapterAddresses.Next;
Er zeigt auf was Anderes und über die Schleife wird so lange weitergemacht, bis NIL im pAdapterAddresses drinsteht. Schau dir einfach nochmal meinen Beispielcode im anderem Thread an und achte auf diese Variable(n). Zitat:
|
AW: Problem mit Speicherfreigabe bei dynamischen Array als function-Übergabe
also ich hab es jetzt so gemacht:
Delphi-Quellcode:
function NetzwerkInfos_auslesen(var Liste: TAdapter_Array; out ErrorCode: Integer): Boolean;
var pAdapterList : PIP_ADAPTER_INFO; pAdapterAddresses : PIP_ADAPTER_ADDRESSES; pAdapterList_store : PIP_ADAPTER_INFO; pAdapterAddresses_store : PIP_ADAPTER_ADDRESSES; begin {...} //Speicher anfordern pAdapterList := AllocMem(LenAdapter_List); pAdapterAddresses := AllocMem(LenAdapter_Address); //Größe des angeforderten Speichers merken, notwendig für das FreeMem //(die normalen Variablen werden nil und dadurch bleibt Speicher übrig) pAdapterList_store := pAdapterList; pAdapterAddresses_store := pAdapterAddresses; try {...} finally // FreeMem(pAdapterList_store); FreeMem(pAdapterAddresses_store); end; end; Zitat:
"Kleine Lecks machen auch Speichermist" |
AW: Problem mit Speicherfreigabe bei dynamischen Array als function-Übergabe
Delphi-Quellcode:
<== entweder ErrorCode als Result oder True/False als Erfolg/Misserfolg-Result aber Beides zusammen ist überbestimmt.
function NetzwerkInfos_auslesen(var Liste: TAdapter_Array; out ErrorCode: Integer): Boolean;
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:44 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