我无法弄清楚 EurekaLog 为我的程序报告的内存泄漏。我正在使用 Delphi 2009。这是:
Memory Leak: Type=Data; Total size=26; Count=1;
The stack is:
System.pas _UStrSetLength 17477
System.pas _UStrCat 17572
Process.pas InputGedcomFile 1145
这就是堆栈中的全部内容。 EurekaLog 将我指向未释放的内存最初分配的位置。根据它,我程序中的行是 InputGedcomFile 的第 1145 行。那一行是:
CurStruct0Key := 'HEAD' + Level0Key;
其中 CurStruct0Key 和 Level0Key 在过程中被简单地定义为局部变量,在进入和离开过程时应该由 Delphi 内存管理器动态处理:
var CurStruct0Key, Level0Key: string;
现在我查看系统单元中的 _UStrCat 过程。第 17572 行是:
CALL _UStrSetLength // Set length of Dest
然后我转到系统单元中的 _UStrSetLength 过程,相关行是:
@@isUnicode:
CMP [EAX-skew].StrRec.refCnt,1 // !!! MT safety
JNE @@copyString // not unique, so copy
SUB EAX,rOff // Offset EAX "S" to start of memory block
ADD EDX,EDX // Double length to get size
JO @@overflow
ADD EDX,rOff+2 // Add string rec size
JO @@overflow
PUSH EAX // Put S on stack
MOV EAX,ESP // to pass by reference
CALL _ReallocMem
POP EAX
ADD EAX,rOff // Readjust
MOV [EBX],EAX // Store
MOV [EAX-skew].StrRec.length,ESI
MOV WORD PTR [EAX+ESI*2],0 // Null terminate
TEST EDI,EDI // Was a temp created?
JZ @@exit
PUSH EDI
MOV EAX,ESP
CALL _LStrClr
POP EDI
JMP @@exit
第 17477 行是“CALL _ReallocMem”行。
那么什么是内存泄漏呢?当然,将字符串常量简单地连接到本地字符串变量不应导致内存泄漏。
为什么 EurekaLog 将我指向作为 Delphi 一部分的 _UStrSetLength 例程中的 ReallocMem 行?
这是 Delphi 2009,我正在使用新的 unicode 字符串。
如有任何帮助或解释,我们将不胜感激。
找到的解决方案:
字符串被分配给新菜单项的属性。菜单项已添加到菜单中。然后新的菜单项被释放,因此我认为一切都被清理干净了。因为字符串(通过引用计数)仍在使用,因为它被复制到项目中,所以字符串没有在内存中释放,即使它在例程中作为局部变量引入也是如此。
通常这不应该是泄漏。但是,我的程序有时会使用“menu.item.delete(i)”删除各种菜单项。我没有意识到的是删除不会释放项目本身的内存。因此,引用计数的字符串没有被释放,从而导致泄漏。
解决方案是将我的“menu.item.delete(i)”语句更改为:“menu.item[i].free”。
最佳答案
它会将您指向分配相关内存的那一行。你是对的,处理字符串应该由编译器处理。您可能遇到了以下两个问题之一。
- 这不是您泄露的唯一内容。该字符串属于一个永远不会被清理的对象。例如,CurStruct0Key 可能会传递给构造函数,并在构造函数中将其分配给对象。或者
- 您正在对字符串做一些棘手的事情,例如将其转换为指针并四处传递。不要这样做!它可以阻止引用计数!
检查是否是这些原因导致了您的问题。
关于delphi - 是什么导致了 Delphi 中的内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1977355/