AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Wie Speicherleck beheben (GetWindowsLanguage)?

Ein Thema von BlueStarHH · begonnen am 8. Jul 2020 · letzter Beitrag vom 8. Jul 2020
Antwort Antwort
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hamburg
849 Beiträge
 
Delphi 11 Alexandria
 
#1

Wie Speicherleck beheben (GetWindowsLanguage)?

  Alt 8. Jul 2020, 11:34
Hallo,

ich ermittele die "Language ID" (Sprache von Windows) mit diesem Code:

Delphi-Quellcode:
function GetWindowsLanguage(LCTYPE: LCTYPE {type of information}): string;
var
  Buffer : PChar;
  Size : integer;
begin
  Size := GetLocaleInfo (LOCALE_USER_DEFAULT, LCType, nil, 0);
  GetMem(Buffer, Size);
  try
    GetLocaleInfo (LOCALE_USER_DEFAULT, LCTYPE, Buffer, Size);
    Result := string(Buffer);
  finally
    FreeMem(Buffer); <-- Speicherleck hier
  end;
end;

Aufruf mit:
GetWindowsLanguage(LOCALE_ILANGUAGE);
gefunden unter https://www.swissdelphicenter.ch/de/showcode.php?id=320

Nun habe ich FastMM5 eingebunden und der zeigt an, dass es ein Speicherleck gibt:
Code:
---------------------------
Memory Corruption Detected
---------------------------
A memory block footer has been corrupted.
The block size is 5.
The block was allocated by thread 0x1C3C, and the stack trace (return addresses) at the time was:

00425680 [FastMM5.pas][FastMM5][FastMM_DebugGetMem_GetDebugBlock][7292]
004256FB [FastMM5.pas][FastMM5][FastMM_DebugGetMem][7315]
0040755E [System][System][@GetMem]
00BF9A33 [test.pas][test][GetWindowsLanguage][20235]
....
The allocation number is: 51923

Current memory dump of 13 bytes starting at pointer address 8333020:
30 00 34 00 30 00 37 00 00 00 80 80 80
0  . 4  . 0  . 7  . . . . . .

Wie kann ich das beheben?
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#2

AW: Wie Speicherleck beheben (GetWindowsLanguage)?

  Alt 8. Jul 2020, 11:59
Da steht nichts von Speicherleck (Memory leak) sondern was von Speicherkorrumpierung (Memory Corruption).

Das liegt mit Sicherheit daran, dass der Größenparameter bei GetMem in Bytes anzugeben ist, GetLocaleInfo aber die Anzahl Zeichen zurückgibt. Du musst also deinen Buffer mit der Größe von Char multiplizieren:
Delphi-Quellcode:
GetMem(Buffer, Size * SizeOf(Char));
_
Nur nebenbei: MS schreibt zu GetLocaleInfoEx:
Zitat:
Starting with Windows Vista, your applications should not use LOCALE_ILANGUAGE in the LCType parameter to avoid failure or retrieval of unexpected data. Instead, it is recommended for your applications to call GetLocaleInfoEx.
Ist völlig bescheuert, dass die schreiben, man solle genau diese Funktion rufen, aber das wird wohl ein Dokumentationsfehler sein.

Grüße
Dalai
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
681 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Wie Speicherleck beheben (GetWindowsLanguage)?

  Alt 8. Jul 2020, 12:02
Hallo,
ich würde nachsehen was Windows für eine maximale Länge für den String angibt und mit einem Array fester länge arbeiten.

Delphi-Quellcode:
var
  buffer: array[0..MaxBufferLength] of PChar;
begin
  GetLocaleInfo (LOCALE_USER_DEFAULT, LCTYPE, buffer, SizeOf(buffer));
  Result := string(buffer);
end;
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.159 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Wie Speicherleck beheben (GetWindowsLanguage)?

  Alt 8. Jul 2020, 12:06
Wenn, dann aber Array of Char, und nicht PChar, oder?

Jedenfalls ist es das was System.SysUtils auch macht:

Delphi-Quellcode:
function GetLocaleStr(Locale, LocaleType: Integer; const Default: string): string;
{$IFDEF MSWINDOWS}
var
  L: Integer;
  Buffer: array[0..255] of Char;
begin
  L := GetLocaleInfo(Locale, LocaleType, Buffer, Length(Buffer));
  if L > 0 then SetString(Result, Buffer, L - 1) else Result := Default;
end;
{$ENDIF MSWINDOWS}
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.071 Beiträge
 
Delphi 12 Athens
 
#5

AW: Wie Speicherleck beheben (GetWindowsLanguage)?

  Alt 8. Jul 2020, 12:07
Statt sowas wie GetMem verwende ich gern SetLength mit einem TBytes. (falls ich das statische Array nicht auf dem Stack liegen haben möchte, siehe Sinspin, bzw. wenn es eine dynamische Länge hat)
Vorteile:
* der Speicher wird automatisch freigegeben
* und er Debugger hat einen Standard-Viewer für diesen Typen (dynamische Arrays)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
BlueStarHH

Registriert seit: 28. Mär 2005
Ort: Hamburg
849 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Wie Speicherleck beheben (GetWindowsLanguage)?

  Alt 8. Jul 2020, 13:10
Wenn, dann aber Array of Char, und nicht PChar, oder?

Jedenfalls ist es das was System.SysUtils auch macht:

Delphi-Quellcode:
function GetLocaleStr(Locale, LocaleType: Integer; const Default: string): string;
{$IFDEF MSWINDOWS}
var
  L: Integer;
  Buffer: array[0..255] of Char;
begin
  L := GetLocaleInfo(Locale, LocaleType, Buffer, Length(Buffer));
  if L > 0 then SetString(Result, Buffer, L - 1) else Result := Default;
end;
{$ENDIF MSWINDOWS}
Danke, so klappt es!
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
681 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Wie Speicherleck beheben (GetWindowsLanguage)?

  Alt 8. Jul 2020, 17:43
Wenn, dann aber Array of Char, und nicht PChar, oder?
Jawoll, auf jeden Fall kein _P_...! Danke fürs aufpassen
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:00 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