我似乎创建了破坏内存的代码。
之前从未遇到过这样的问题,我现在设置了一个无效的指针操作。
在下面,我调用PromptForXYZPropertiesSettings后,const字符串sFilename的值被删除。
// Allow the user to quickly display the properties of XYZ without needing to display the full Editor
function PromptForXYZProperties(const sFilename:string; var AXYZProperties: TXYZProperties): boolean;
var
PropEditor: TdlgEditor;
begin
PropEditor:= TdlgEditor.create(nil);
try
PropEditor.LoadFromFile(sFilename); <-- sFilename = 'C:\My Folder\Some Folder.txt'
PropEditor.SelectedXYZProperties := AXYZProperties;
// Bypass PropEditor to show form owned by it
Result := PropEditor.PromptForXYZPropertiesSettings;
if Result then
begin
PropEditor.SaveToFile(sFilename); <-- sFilename now somethign like 'B'#1#0#0'ë' or value of a different var
end;
finally
PropEditor.free;
end;
end;
其他细节:
所以我想就如何调试问题提出一些建议。我想也许正在观察sFilename var存在的内存指针以查看它被删除的位置,但不确定我将如何做到(显然需要在应用程序中完成,因此拥有内存)。
由于
答案 0 :(得分:6)
听起来像是在捣乱你的筹码。从随便看看你的代码我看不出任何明显的正确性问题。您有正确的想法:要跟踪此情况,您需要监控字符串的值并查看其更改时间。这是你如何做到的:
sFilename
并双击它。sFileame: string $18FEA8 : $4A0E5C
。这两个十六进制值分别是字符串引用的位置和字符串数据本身。答案 1 :(得分:1)
我怀疑TdlgEditor.LoadFromFile
(或调用堆栈中的某些代码)中的某些代码通过指针访问字符串(在这种情况下,编译器无法强制执行const
- )。登记/>
string
/ AnsiString
变量实际上是由编译器内部处理的重新计数记录,不应通过指针访问进行更改。
只要您无法更改TdlgEditor
类,您的解决方案可能实际上是正确的 - 您制作字符串的本地副本,因此您不必关心它是否在此过程中被打破,您只需必须记住不在调用后假设有关本地字符串内容的任何内容。
答案 2 :(得分:0)
通常无效指针操作在将无效指针传递给MM的例程时发生。就像两次释放内存一样。内存损坏通常会导致访问冲突。
我认为您应该首先使用debugging memory manager in debug mode。
答案 3 :(得分:0)
我认为您的PromptForXYZPropertiesSettings
内部调用ShowModal()
,如果TdlgEditor
在关闭时设置为免费(FormClose
事件设置CloseAction := caFree
),那么当流程时执行返回到您的代码,dlgEditor
对象已被销毁,因此无效。
这也可以解释无效指针操作,因为您试图在Free
代码中释放已经finally dlgEditor.Free
的对象。
如果是这种情况,那么您应该将TdlgEditor
更改为仅在关闭时隐藏,并在FormClose事件中设置CloseAction := caHide
。