为什么调用GetMem会导致内存泄漏?

时间:2013-03-11 16:03:10

标签: delphi

我有这段代码来查看我的前台窗口是否是SDImainframe。

Function Active_window_mf() :Boolean;
var
  FromClass: PChar;
begin

  MFhandle := GetForeGroundWindow;
  GetMem(FromClass, 100);
  GetClassName(MFhandle, PChar(FromClass), 800);
  if StrPas(FromClass) = 'SDIMainFrame' then
    result := true;
end;

但是,MADExcept报告Getmem功能存在问题。任何人都可以建议,我的代码有什么问题吗?

1 个答案:

答案 0 :(得分:16)

您的代码中存在三个问题。 首先,如果您分配内存(GetMem),则需要释放它(FreeMem):

GetMem(p, 1024);
try
  // Do sth with the memory
finally
  FreeMem(p);
end;

第二次,我看不到100800之间的关系。事实上,你说谎。您分配一个100字节的缓冲区,然后告诉Windows它足够大,可以容纳800个Unicode字符。

第三,除非比较为真,否则函数的返回值是未定义的。因此,您需要将result := false添加到过程的开头,或者通过

替换最后两行(end;之前)
result := string(FromClass) = 'SDIMainFrame'

无论如何,最好不要使用GetMem。我会这样做:

var
  CN: array[0..256] of char;
begin
  GetClassName(MFhandle, CN, 256)

此外,您应该检查错误。如果GetClassName返回0,则会发生错误。因此,您可以执行类似

的操作
function Active_window_mf(): boolean;
var
  CN: array[0..256] of char;
begin
  result := false;
  if GetClassName(GetForegroundWindow, CN, 257) > 0 then
    result := string(CN) = 'SDIMainFrame';
end;

更新:根据David关于抽象级别的优秀观点,这样做会很好:

function ClassNameFromHWND(const Handle: HWND): string;
var
  CN: array[0..256] of char;
begin
  result := '';
  if GetClassName(Handle, CN, 257) > 0 then
    result := CN;
end;

function Active_window_mf(): boolean;
begin
  result := ClassNameFromHWND(GetForegroundWindow) = 'SDIMainForm';
end;