问题标签 [heap-corruption]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
9 回答
4425 浏览

c++ - 将指向堆栈变量的指针传递给 realloc() 是否有效?

似乎工作正常,但我仍然对堆栈与堆有点困惑。这是允许的吗?如果允许,是否myString需要手动释放或者超出范围时是否会释放?


编辑:感谢您的回复,所以我认为这同样是非法的

0 投票
15 回答
192837 浏览

c++ - 如何调试堆损坏错误?

我正在 Visual Studio 2008 下调试(本机)多线程 C++ 应用程序。在看似随机的情况下,我收到“Windows 已触发断点...”错误,并指出这可能是由于堆。这些错误不会总是立即使应用程序崩溃,尽管它可能会在不久之后崩溃。

这些错误的最大问题是它们仅在实际发生损坏后才会弹出,这使得它们很难跟踪和调试,尤其是在多线程应用程序上。

  • 什么样的事情会导致这些错误?

  • 我该如何调试它们?

欢迎使用提示、工具、方法、启示……。

0 投票
5 回答
1454 浏览

c++ - 处理破坏堆的对象

在我的应用程序中,我正在创建一个非常像这样的对象:

一旦我即将关闭应用程序,我称之为:

此调用始终触发带有以下消息的断点:

Windows 已在 DesignerDynD.exe 中触发断点。

这可能是由于堆损坏,这表明 DesignerDynD.exe 或其已加载的任何 DLL 中存在错误。

这也可能是由于在 DesignerDynD.exe 具有焦点时用户按 F12。

输出窗口可能有更多诊断信息。

我无法修改 vhtGlove 类来修复堆栈的损坏,因为它是一个仅以头文件、lib 文件和 dll 的形式提供的外部库。

有没有办法以干净的方式使用这个类?


**** 编辑 ::: 我试图将事情精简到最低限度,但是我得到了相同的结果......在这里你有整个代码。

删除手套时仍然崩溃。


编辑#2 :: 如果我只是分配和删除 vhtCyber​​Glove 的一个实例,它也会崩溃。

有任何想法吗?

谢谢!

JC

0 投票
8 回答
1734 浏览

c++ - 堆损坏

如果我们在 char 数组的 new 和 delete 之间有一大段代码,为什么会出现问题。

例子

0 投票
7 回答
3375 浏览

c++ - 删除指针有时会导致堆损坏

我有一个使用自定义线程池类运行的多线程应用程序。线程都执行相同的函数,但参数不同。

这些参数通过以下方式提供给线程池类:

一旦一个线程无事可做,它就获取下一个参数并运行作业函数。我决定删除线程池类中的参数:

但是,这样做时,有时会出现堆损坏错误:

指定给 RtlFreeHeap 的地址无效

奇怪的是,在一种情况下它可以完美运行,但在另一个程序中它会因这个错误而崩溃。我尝试在其他地方删除指针:在作业函数执行后的线程中(我得到相同的堆损坏错误)或在作业函数本身的末尾(在这种情况下没有错误)。

我不明白从不同的地方删除相同的指针(我检查过,地址是相同的)如何改变任何东西。这与它是多线程的事实有什么关系吗?

我确实有一个关键部分来处理对参数的访问。我认为问题不在于同步访问。无论如何,只有在所有线程完成后才会调用析构函数,并且我不会在其他任何地方删除任何指针。指针可以自动删除吗?

至于我的代码。作业列表是一个结构的队列,由作业的id(用于以后能够获取特定作业的输出)和参数组成。

getNextJob()每次完成执行最后一个作业时,线程都会调用它(它们有一个指向 ThreadPool 的指针)。

0 投票
2 回答
449 浏览

c++ - priority_queue 的问题 - 在堆后写入内存

我正在尝试使用priority_queue,并且程序不断失败并出现错误消息HEAP CORRUPTION DETECTED。

以下是片段:

类 Message 具有重载的运算符 > 和 <

在这里我填满队列:

在主程序中:

我不知道似乎是什么问题。当我推送大约 8 个项目时会发生这种情况,并且在线失败

在 <队列>

:(

这是消息类的定义——非常简单:

};

Poruka - 消息

0 投票
1 回答
137 浏览

heap-corruption - 已发布/生产版本出现堆损坏。解决方案阻止它?

在我们公司,我们不知何故将代码投入生产,但崩溃了(因为堆以某种方式损坏)。开发人员开发,然后测试人员动手,然后以自然方式发布(每月发布)。一切都很好,直到它崩溃了......我们试图调查它并发现了很多我们可以得到堆损坏的地方......我们可以做些什么来防止这些东西?破坏我们的代码审查(我们一直有 4/5,只有 1 名开发人员在没有任何编码人员帮助的情况下这样做)?仅通过智能指针或其他方式改变我们的内存管理策略?任何建议都会很好!

0 投票
3 回答
895 浏览

heap-memory - _CrtCheckMemory 函数返回前后

以下代码:

调试器陷入第二个 _CrtCheckMemory() 中的 heapcheck 函数,告诉我堆有问题 - 所以我的假设是我的 generate_poisson 函数搞砸了。但是 - 如果我添加一个 _CrtCheckMemory(); 在 generate_poisson 函数的末尾直接调用,就在 return 之前,那么调试器仍然像以前一样在同一行捕获,而不是在新添加的 _CrtCheckMemory()

这意味着什么?

谢谢!

//edit: 是否有可能是另一个线程搞砸了堆,或者 _CrtCheckMemory() 是否只检查当前线程的堆?

0 投票
10 回答
2704 浏览

delphi - 在 Delphi 中检测 VMT 或堆损坏的正确工具是什么?

我是一个将 Delphi 2007 用于大型应用程序的团队的成员,我们怀疑堆损坏,因为有时会出现没有其他解释的奇怪错误。我相信编译器的 Rangechecking 选项仅适用于数组。我想要一个工具,当在应用程序未分配的内存地址上写入时,它会给出异常或日志。

问候

编辑:错误类型:

错误:模块“BoatLogisticsAMCAttracsServer.exe”中地址 00404E78 的访问冲突。读取地址 FFFFFFDD

EDIT2:感谢所有建议。不幸的是,我认为解决方案比这更深。由于我们拥有源代码,因此我们为 Delphi 使用了 Bold 的补丁版本。可能在 Bold 框架中引入了一些错误。是的,我们有一个日志,其中包含由 JCL 处理的调用堆栈以及跟踪消息。所以带有异常的调用栈可以像这样锁定:

内部异常部分是重新引发异常时的调用堆栈。

EDIT3:现在的理论是虚拟内存表(VMT)以某种方式损坏。当这种情况发生时,没有任何迹象。只有在调用方法时才会引发异常(始终在地址 FFFFFFDD,-35 十进制),但为时已晚。您不知道错误的真正原因。任何关于如何捕获这样的错误的提示都非常感谢!!!我们尝试过使用 SafeMM,但问题是即使使用 3 GB 标志,内存消耗也太高。所以现在我试着给 SO 社区一个赏金:)

EDIT4:一个提示是,根据日志,在此之前经常(甚至总是)另一个异常。例如,它可以是数据库中的乐观锁定。我们试图强制引发异常,但在测试环境中它工作正常。

EDIT5:故事还在继续……我现在对过去 30 天的日志进行了搜索。结果:

  • “读取地址 FFFFFFDB” 0
  • “读取地址 FFFFFFDC” 24
  • “读取地址 FFFFFFDD” 270
  • “读取地址 FFFFFFDE” 22
  • “读取地址 FFFFFFDF” 7
  • “读取地址 FFFFFFE0” 20
  • “读取地址 FFFFFFE1” 0

所以目前的理论是一个枚举(有很多粗体)覆盖一个指针。我在上面得到了 5 个不同地址的点击。这可能意味着枚举包含 5 个值,其中第二个是最常用的。如果出现异常,则应为数据库进行回滚,并且应销毁 Boldobjects。也许不是所有东西都被破坏了,枚举仍然可以写入地址位置。如果这是真的,也许可以通过正则表达式搜索代码以查找具有 5 个值的枚举?

EDIT6:总而言之,还没有解决问题的方法。我意识到我可能会用调用堆栈误导你。是的,其中有一个计时器,但还有其他没有计时器的调用堆栈。对此感到抱歉。但有两个共同因素。

  • 读取地址 FFFFFFxx 的异常。
  • 调用堆栈的顶部是 System.TObject.InheritsFrom (sys\system.pas:9237)

这让我相信VilleK最能描述这个问题。我也确信问题出在 Bold 框架的某个地方。但最大的问题是,如何解决这样的问题?仅仅有一个像VilleK这样的断言是不够的,因为损坏已经发生并且调用堆栈在那一刻已经消失了。因此,描述我对可能导致错误的原因的看法:

  1. 某个地方的指针被分配了一个错误的值 1,但它也可以是 0、2、3 等。
  2. 一个对象被分配给该指针。
  3. 对象基类中有方法调用。这会导致方法 TObject.InheritsForm 被调用,并且地址 FFFFFFDD 上出现异常。

这 3 个事件可以在代码中一起使用,但也可以在以后使用。我认为这对于最后一个方法调用是正确的。

EDIT7:我们与 Bold Jan Norden 的作者密切合作,他最近在 Bold 框架中的 OCL 评估器中发现了一个错误。修复此问题后,这些异常减少了很多,但它们仍然偶尔会出现。但这是一个很大的安慰,这几乎解决了。

0 投票
3 回答
876 浏览

c++ - 在 C++ 中调试参数损坏?

我的项目中有一个插件系统(在 linux 上运行),其中一部分是插件有一个“运行”方法,例如:

我正在调用我的插件并检查我的 argv 数组(在做了一堆其他事情之后),并且该数组已损坏。我可以在函数顶部打印出这些值,它们是正确的,但在稍后的执行中就不行了。显然有些东西正在破坏堆,但我不知道如何尝试准确地确定覆盖该内存的内容。Valgrind 对我帮助不大。

按要求提供示例代码:

我的插件看起来像这样:

这被链接到一个将其暴露给 python 的系统,因此我可以将这些插件称为 python 函数。因此,我将一个字符串参数带到我的 python 函数中,然后将其分解:

然后将生成的 argc 和 argv 传递给上面提到的插件。