在 FreeAndNil 之后使用对象时会发生什么?

2023-11-21

在我的Delphi7中这段代码

var MStr: TMemoryStream;
...
FreeAndNil(MStr);
MStr.Size:=0; 

生成 AV:模块“Project1.exe”中地址 0041D6D1 处的访问冲突。读取地址 00000000。 但有人坚持认为,无论如何都不应该提出任何例外。他还说他的 Delphi 5 确实没有例外。他称之为“陈旧指针错误”。 换句话说,他说 FreeAndNil 不能用作调试器来检测释放对象或使用已释放对象的双重尝试。

有人可以启发我吗?是否应该引发错误(总是/随机),或者程序应该毫无问题地运行此错误?

Thanks


我问这个问题是因为我相信我的程序中有“双重释放对象”或“释放并重新访问”错误。释放对象后,如何用零填充分配给对象的内存?我希望通过获取 AV 的方式来检测 bug 的位置。 最初,我希望如果我将对象设置为 FreeAndNil,当我尝试重新访问它时,我总是会得到一个 AV。


使用空引用的方法或属性总是错误的,即使它有时看起来有效。

FreeAndNil确实不能用于检测双重释放。打电话是安全的FreeAndNil在一个已经为零的变量上。因为它是安全的,所以它不能帮助您检测任何东西。

这不是陈旧指针错误。这是一个空引用错误。陈旧指针错误是指当您释放了一个对象但not清除引用它的所有变量。那么该变量仍然保存着对象的旧地址。这些很难被发现。你可能会遇到这样的错误:

MStr := TMemoryStream.Create;
MStr.Free;
MStr.Size := 0;

您还可以获得这样的一个:

MStr := TMemoryStream.Create;
OtherStr := MStr;
FreeAndNil(MStr);
OtherStr.Size := 0;

Using MStr.Size释放对象后MStr引用是一个错误,它应该引发异常。无论does引发异常取决于实现。也许会,也许不会。但这不是随机的。

如果您正在寻找双重释放错误,您可以使用 FastMM 提供的调试助手,正如其他人所建议的那样。它的工作原理是实际上并不将内存释放回操作系统,甚至不释放回 Delphi 的内部空闲内存池。相反,它将已知的错误数据写入对象的内存空间,因此当您看到这些值时,您就会知道您正在读取已经释放的内容。它还修改对象的 VMT,以便下次在该对象引用上调用虚拟方法时,您将得到一个可预测的异常,它甚至会告诉您尝试使用哪个所谓的已释放对象。当您尝试再次释放该对象时,它不仅可以告诉您已经释放了它,还可以告诉您第一次释放它的位置(带有堆栈跟踪)以及它被分配的位置。它还收集该信息以报告内存泄漏(您在其中释放了对象)less不止一次而不是更多。

您还可以使用一些习惯来避免将来的代码出现问题:

  • 减少全局变量的使用。全局变量可以被整个程序中的任何代码修改,迫使您在使用它时想知道“这个变量的值仍然有效,还是其他代码已经释放了它?”当您限制变量的范围时,您可以减少程序中查找变量不具有预期值的原因时必须考虑的代码量。
  • 明确谁拥有某个对象。当有两段代码可以访问同一个对象时,您需要知道哪一段代码owns物体。它们可能都有一个不同的变量来引用该对象,但那里仍然只有一个对象。如果一段代码调用FreeAndNil在它的变量上,仍然保持其他代码的变量不变。如果其他代码认为它拥有该对象,那么您就有麻烦了。 (所有者的概念不一定与TComponent.Owner财产。不需要有一个object拥有它的人;它可能是您程序的通用子系统。)
  • 不要保留对不属于您的对象的持久引用。如果您不保留对对象的长期引用,那么您不必担心这些引用是否仍然有效。唯一的持久引用应该位于拥有该对象的代码中。任何其他需要使用该对象的代码都应该接收引用作为输入参数,使用该对象,然后在返回结果时丢弃该引用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 FreeAndNil 之后使用对象时会发生什么? 的相关文章

  • Delphi 2010 控制闪烁

    我一直在从 XP 操作系统升级或迁移我们的软件 以便能够在 Windows 7 下编译和运行 我们的软件开始出现我们在 Windows XP 下没有注意到的问题 目前 我正在处理 TForm 上闪烁的用户定义控件 它似乎时不时地闪烁 但并非
  • delphi检查ini文件是否存在

    如何检查 INI 文件是否存在 在特定路径和特定名称下 比如这样 if FileExists c yourinifile ini then ShowMessage c yourinifile ini exists
  • Delphi - 如何将通用参数传递给接受 const 参数数组的函数

    我有一个 基类 其中包含一个 函数 该函数接受 const 数组 类型的参数 如下所示 type TBaseClass class TObject public procedure NotifyAll const AParams array
  • 如何安装DBMonitor

    这可能是一个非常简单的问题 但就是这样 我刚刚更新了 Firebird 的 DevArt DBExpress 驱动程序的许可证 帮助文件说我可以使用他们的免费软件 DBMonitor 应用程序 但由于我使用的是 D2006 所以我必须使用以
  • XE2 中的 COM 是否损坏?我该如何解决它?

    Update XE2 Update 2 修复了下述错误 下面的程序是从实际程序中截取的 在 XE2 中失败并出现异常 这是 2010 年的回归 我没有 XE 来测试 但我希望该程序在 XE 上运行良好 感谢 Primo 确认代码在 XE 上
  • 在 Delphi 中强制非阻塞临时提示窗口

    我一直在寻找 但找不到解决方案 所以我想也许我应该简单地发布它 这是我想要在 Delphi 2009 中做的事情 在我的应用程序中的某个时刻 我想向用户显示一条消息 这应该是正常的提示窗口 在正常应用程序定义的提示暂停后自动消失 并带有自定
  • Delphi 如何与 Active Directory 集成?

    我们需要使用 Delphi 7 验证 Microsoft Active Directory 上的用户 最好的方法是什么 我们可以有两种情况 用户输入其网络用户名和密码 其中用户名可能包括域 然后我们检查活动目录是否是有效的活动用户 或者我们
  • 如何更改 Delphi 2010 IDE 中编辑器选项卡的字体大小?

    有谁知道如何更改 Delphi 2010 IDE 中编辑器选项卡的字体大小 我的 1080p 22 显示器的字体太小 无法阅读 而且会导致眼睛疼痛 一些笔记 它不尊重系统的 DPI 设置 因此更改系统设置没有帮助 而且 我现在已经使用 14
  • 如何从具有管理员权限的应用程序接收键盘输入到非管理员应用程序?

    我编写了一个应用程序 该应用程序具有覆盖类型的窗口 可以通过热键显示和隐藏该窗口 而另一个应用程序具有焦点 所述另一个应用程序是一个以管理员权限运行的 DirectX 游戏 我已经尝试了 3 种可能的解决方案 以便在其他应用程序中按下我的热
  • 如何在滚动框上创建缓慢的滚动效果?

    我喜欢在滚动框中平移图像后创建平滑的减慢滚动效果 就像平移地图一样谷歌地图 http maps google com 我不确定它是什么类型 但行为完全相同 当快速移动地图时 当您释放鼠标时它不会立即停止 而是开始减慢速度 有什么想法 组件
  • Indy 的 TIdHTTPProxyServer:如何过滤请求?

    我正在使用 TIdHTTPProxyServer 来实现一个简单的 HTTP 代理 但我现在想阻止一些与某些 URL 匹配的连接 哪个事件和 或组件最适合实现这一目标 Indy 文档并没有太多解释 Thanks 作为基本过滤器 您可以使用
  • 我可以让我的 Delphi 应用程序在特定时间(例如上午 12:00)启动,而不运行应用程序吗?

    我看到一个已安装的应用程序 它从供应商的网站提供一些 XML 数据并将其显示在主窗体窗口中 我想这很简单 但我注意到 即使我关闭系统托盘中的应用程序 明天早上 上午 12 00 正好 它也会再次弹出 这太酷了 我不确定它是用 Delphi
  • 如何将 REST API 与 FireMonkey 结合使用?

    我需要在 FireMonkey 中实现 REST API 来获取一些信息 但我不确定如何做到这一点 REST API使用OAuth2 我可以访问两个代码 Consumer Key和Consumer Secret 之后 我需要获得一个临时的
  • 德尔福数据结构

    我可能需要在 Delphi 中做一个项目 并且是该领域的初学者 目前 我正在网上搜索资源 但由于资源站点太少而感到困惑 首先 你能给我一些好的网站 其中包含我迄今为止错过的 Delphi 资源吗 我也在 Delphi 中搜索数据结构 想知道
  • 我如何在Delphi中处理事件?

    例如 我有一个程序 在单击 Button1 后执行某些操作 如果没有 Button1Click 中的代码 如何处理按钮的 onclick 事件 我需要为 Button1 动态添加事件 unit Unit1 interface uses Wi
  • 处理 TShellListView 后代中的文件放置

    我正在尝试创建 TShellListView 的后代 它接受从 Windows 资源管理器中删除的文件 我想在组件定义中处理拖 放操作 而不必在任何使用该组件的应用程序中实现它 我找到了接受从 Windows 资源管理器中拖放的文件的示例
  • 如何在 Delphi DBLookupComboBox 中选择正确的项目

    我有一个数据库查找组合框连接到数据库查询 那部分工作正常 当我运行程序时数据库查找组合框填充有查询的结果 我想看看数据库查找组合框填充第一项 请选择 当 的时候程序第一次运行或者当一个新项目行动已启动 见下图 另外 如果我正在加载以前保存的
  • 为什么未初始化的指针会导致内存访问冲突接近 0?

    据说often 但并非总是如此 当你在接近于零的内存位置 比如 89 美元 获得 AV 时 你就有了一个未初始化的指针 但我也在 Delphi 书籍中看到了这一点 嗯 或者它们都是由同一作者写的 Update 引自 Bob Swart 等人
  • delphi中如何实现多重继承?

    我正在对一个旧库进行完全重写 我不确定如何处理这种情况 为了便于理解 大家都欢呼自行车类比 我有以下课程 TBike 自行车本身 TBikeWheel 自行车的一个轮子 TBikeWheelFront and TBikeWheelBack
  • TObjectList.Contains 导致 Delphi 2009 中的访问冲突

    在 Delphi 2009 中 到目前为止 我在泛型方面没有遇到大问题 使用 Generics Collections 列表 没有特殊的泛型功能 现在我发现这段代码会在访问的行中导致AVMyList Contains 如果我声明 TMyLi

随机推荐

  • 如何从 Android 手机获取时区?

    我想在单击按钮时从 Android 手机获取时区 您是否尝试过使用TimeZone getDefault 大多数应用程序都会使用时区 getDefault 它返回一个基于时区的 程序运行所在的时区 Ref http developer an
  • Django仅在生产环境中使用私有S3存储

    我已将 django REST API 设置为在调试模式下使用本地存储 在生产环境中使用 S3 存储 这对于公共文件很有效 因为我覆盖了DEFAULT FILE STORAGE像这样 if IS DEBUG DEFAULT FILE STO
  • 接受多个 Id 值的 T-SQL 存储过程

    有没有一种优雅的方法来处理将 id 列表作为参数传递给存储过程 例如 我希望我的存储过程返回部门 1 2 5 7 20 过去 我传递了一个逗号分隔的 id 列表 如下面的代码 但感觉这样做真的很脏 我认为 SQL Server 2005 是
  • .NET 中的 C# 类何时调用析构函数?

    比如说 我有自己的 C 类 定义如下 public class MyClass public MyClass Do the work MyClass Destructor 然后我从 ASP NET 项目创建类的实例 如下所示 if true
  • Google Chrome .dev 无法通过 http 工作 [重复]

    这个问题在这里已经有答案了 自上次更新以来谷歌浏览器 63 0 3239 84 the dev我的本地开发计算机的域不再工作 因为浏览器强制 URL 通过 https 并且我的本地计算机上没有 sicure 证书 有没有办法让它与 dev
  • 64 位 iOS 设备上的 asm("trap")

    在我自己开发的断言宏中 我一直在 iOS 设备上使用 asm trap 或在 iOS 模拟器上使用 asm int3 来中断调试器 然而 在设备的 64 位版本中 我得到了陷阱指令的 无法识别的指令助记符 有与arm64相当的吗 像 bui
  • 使用 feed_dict 比使用数据集 API 快 5 倍以上?

    我创建了一个 TFRecord 格式的数据集进行测试 每个条目包含 200 列 名为C1 C199 每个都是一个字符串列表 和一个label列来表示标签 创建数据的代码可以在这里找到 https github com codescv tf
  • Pyplot 交互式缩放

    我想显示首次显示时放大的图像 但仍然可以使用图窗工具栏中的交互式 重置原始视图 按钮缩小到全尺寸 裁剪是完全不可接受的 使用plt axis x0 x1 y0 y1 确实允许平移 但交互式窗口不会重置为全尺寸 有没有办法触发情节缩放或以其他
  • AWS Lambda HTTP API 网关集成上不可能实现 CORS

    创建了返回 3 个 HTTP 标头的 AWS Lambda 函数 NodeJS aaa Access Control Allow Origin 和 bbb exports handler async event gt const respo
  • 如何判断一棵二叉树是否完整?

    完全二叉树被定义为其中每个级别 可能除了最深的级别 都被完全填充的二叉树 在最深层 所有节点必须尽可能位于左侧 我认为一个简单的递归算法将能够判断给定的二叉树是否完整 但我似乎无法弄清楚 如同 height t if t NULL then
  • 从关系中选择最常见的值 - SQL 语句

    我的数据库中有一个表 其中包含许多记录 某些记录的其中一列共享相同的值 例如 id name software 1 john photoshop 2 paul photoshop 3 gary textmate 4 ade firework
  • 从 Google App Engine 导出/导入数据存储

    我想将 App Engine 中运行的数据存储导出到应用程序的本地 独立 版本中 有人知道我该怎么做吗 我一直在 App Engine 仪表板中查找 但找不到它 查看文档上传和下载数据
  • 如何通过 RDP 连接到我的 Azure 云服务? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 正如我所读到的 每个 Azure 云服务背后都有一个虚拟机 对吗 我知道 对于虚拟机 我可以单击 连接 按钮来获取 rdp 文件以进行远程登录 但是 对于我的云服务 正在运行 连接
  • Firebase 存储对象的下载 URL 是否永久存在?

    当您将文件上传到 Firebase 的存储然后询问对象 URL 时 您会得到一个可公开访问的 URL 例如http firebasestorage googleapis com v0 b appname o filename alt med
  • Android:在哪里可以找到 RadioButton Drawable?

    好的 我正在尝试创建一个名为的自定义视图CheckedRelativeLayout 它的目的与CheckedTextView 以便能够在您想要选择的项目列表中或在Spinner 现在一切正常 我延长了RelativeLayout并实施了Ch
  • 是否可以代表用户在我的网站上禁用第三方 cookie?

    我有一个从另一个网站加载资源的网站 我已经能够确定 第三方网站在用户的浏览器上放置cookie 如果我在浏览器设置中禁用第三方 Cookie 则第三方网站将无法再在浏览器上放置 Cookie 该资源仍然可以正常工作 我想知道我是否可以从我的
  • 内核崩溃后获取 Linux 内核调试信息

    有没有办法在内核崩溃发生后获取内核以前的调试信息 我正在尝试开发一个内核模块 它基本上捕获内核网络堆栈内IP层中的IP数据包 经过一些修改后 我必须将相同的数据包发送回NIC进行传输 在所有这些过程中 我在以下的帮助下编写调试信息print
  • 在div中隐藏滚动条

    有没有办法使用CSS隐藏滚动条同时仍保留其功能 甚至使其透明或与背景颜色相同也可以 我必须在 JavaScript 中执行此操作吗 className overflow auto overflow y hidden 我相信用户必须使用鼠标滚
  • 当绑定的列表视图没有项目时显示一些文本

    以下是我的列表视图的语法 它绑定到一个类
  • 在 FreeAndNil 之后使用对象时会发生什么?

    在我的Delphi7中这段代码 var MStr TMemoryStream FreeAndNil MStr MStr Size 0 生成 AV 模块 Project1 exe 中地址 0041D6D1 处的访问冲突 读取地址 000000