无效的指针操作,通过调试请求的建议

时间:2010-05-31 22:50:32

标签: delphi memory

我似乎创建了破坏内存的代码。

之前从未遇到过这样的问题,我现在设置了一个无效的指针操作。

在下面,我调用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;

其他细节:

  • Delphi 2007,Windows 7 64位,但是 可以在XP上测试EXE时重现
  • 从展览中删除CONST STOPS问题(但可能是 问题因此只是潜伏)
  • PropEditor.PromptForXYZPropertiesSettings 创建并显示表单。如果我 禁用ShowModal调用然后 记忆没有被破坏。即使我 已删除所有控制和代码 来自表格

所以我想就如何调试问题提出一些建议。我想也许正在观察sFilename var存在的内存指针以查看它被删除的位置,但不确定我将如何做到(显然需要在应用程序中完成,因此拥有内存)。

由于

4 个答案:

答案 0 :(得分:6)

听起来像是在捣乱你的筹码。从随便看看你的代码我看不出任何明显的正确性问题。您有正确的想法:要跟踪此情况,您需要监控字符串的值并查看其更改时间。这是你如何做到的:

  • 在方法的第一行放置一个断点。
  • 当它中断时,请查看调试器中的Local Variables视图。找到sFilename并双击它。
  • Debug Inspector窗口将打开。在顶部,它会说出这样的话:sFileame: string $18FEA8 : $4A0E5C。这两个十六进制值分别是字符串引用的位置和字符串数据本身。
  • 按CTRL-ALT-B调出断点列表。它有一个小工具栏,工具栏上的第一个按钮有一个下拉箭头。
  • 单击此箭头并从列表中选择“数据断点”。您将需要为Debug Inspector窗口中的两个值创建两个断点。 (如果它警告你在堆栈上放置一个数据断点,那么无论如何都要这样做,但是你要记得以后清除它。)
  • 一旦设置了两个数据断点值,点击F9。系统将监视这些内存位置,并在修改后中断。从那里你应该能够找到破坏你的字符串的内容。

答案 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

相关问题