大佬教程收集整理的这篇文章主要介绍了尝试释放带有对象的 StringList 时出现的复杂问题使我的应用程序崩溃,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
在windows 10的Delphi 10.4.2 win-32 VCL应用程序中,我用这段代码收集了一些窗口的句柄和程序路径:
function GetPathFromPID(const PID: Cardinal): String;
var
hProcess: THandle;
Path: arraY[0..MAX_PATH - 1] of Char;
begin
hProcess := WinAPI.windows.OpenProcess(WinAPI.windows.process_query_informatION or WinAPI.windows.process_VM_READ,false,PID);
if hProcess <> 0 then
try
if WinAPI.PsAPI.GetmodulefilenameEx(hProcess,Path,WinAPI.windows.MAX_PATH) = 0 then
RaiseLastOSError;
Result := Path;
finally
WinAPI.windows.CloseHandle(hProcess)
end
else
RaiseLastOSError;
end;
function EnumWinProc(wHandle: WinAPI.windows.HWND; aList: TStringList): WinAPI.windows.bool; stdcall;
var
strPath: String;
IsAppMainWin: Boolean;
ProcID: Cardinal;
begin
IsAppMainWin := IsWindowVisible(wHandlE) and // Visible
(Getwindow(wHandle,WinAPI.windows.GW_owneR) = 0) and // Not owned by other windows
(GetParent(wHandlE) = 0) and // Does not have any parent
(getwindowlong(wHandle,WinAPI.windows.GWL_EXSTYLE) and WinAPI.windows.WS_EX_TOolWINDOW = 0); // Not a tool window
if IsAppMainWin then
begin
GetwindowThreadProcessID(wHandle,ProcID);
try
strPath := GetPathFromPID(ProcID);
except
strPath := 'UnkNownProgramPath';
end;
aList.Addobject(strPath,TObject(wHandlE));
end;
Result := True;
end;
procedure ClearList(List: TStringList);
// https://stackoverflow.com/questions/9148659/how-to-free-objects-in-StringList-in-delphi-7
var
i: Integer;
begin
// crash occurs here!
for i := 0 to pred(List.Count) do
List.objects[i].Free;
List.Clear;
end;
procedure TformMain.outputAllAppwindows;
begin
var sl := TStringList.Create;
try
sl.ownsObjects := True;
Enumwindows(@EnumWinProc,WinAPI.windows.LParaM(sl));
for var i := 0 to sl.Count - 1 do
begin
CodeSite.Send('window handle',WinAPI.windows.HWND(sl.objects[i]));
CodeSite.Send('program-path sl[i]',sl[i]);
end;
ClearList(sl); // EDIT: forgot this line!
finally
sl.Free;
end;
end;
崩溃是由 EurekaLog 报告的:
2.1 日期:2021 年 7 月 31 日星期六 22:36:53 +0200
2.2 地址:005509D2
2.5 类型:EInvalIDPointer
2.6 消息:应用程序尝试释放无效或未知的内存块:$00010AE2 OBjeCT [?] 0 字节。
2.7 编号:B5002468
2.8 计数:1
2.11 发送:0
这是在 EurekaLog 调用堆栈的顶部:
这里有两个问题:
首先,您将整数作为对象放入字符串列表中,因此您不能将这些“对象”视为对象,因为它们不是。
特别是,没有什么可以释放的,你不能释放这些“对象”;这相当于执行 TObject(some random pointer).Free
。
其次,如果您确实已经将真实对象放入列表中,那么您仍然会遇到错误,因为您首先会自己释放它们,而无需nil
调用它们的引用,所以字符串列表的析构函数会尝试“销毁”这些悬空指针指向的东西。再次,糟糕。
以上是大佬教程为你收集整理的尝试释放带有对象的 StringList 时出现的复杂问题使我的应用程序崩溃全部内容,希望文章能够帮你解决尝试释放带有对象的 StringList 时出现的复杂问题使我的应用程序崩溃所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。