【问题标题】:Heap corruption - "Free Heap block 61af0f0 modified at 61af194 after it was freed" C++堆损坏 - “释放堆块 61af0f0 在被释放后修改为 61af194”C++
【发布时间】:2013-01-04 11:15:29
【问题描述】:

在我的应用程序中出现此错误:

HEAP[App.exe]: HEAP: Free Heap block 61af0f0 modified at 61af194 after it was freed

这是一个调用堆栈:

    ntdll.dll!_RtlpBreakPointHeap@4()   Unknown
    ntdll.dll!@RtlpAllocateHeap@24()    Unknown
    ntdll.dll!_RtlAllocateHeap@12() Unknown
    ntdll.dll!_RtlDebugAllocateHeap@12()    Unknown
    ntdll.dll!@RtlpAllocateHeap@24()    Unknown
    ntdll.dll!_RtlAllocateHeap@12() Unknown
>   msvcr110d.dll!_heap_alloc_base(unsigned int size) Line 57   C
    msvcr110d.dll!_heap_alloc_dbg_impl(unsigned int nSize, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 431 C++
    msvcr110d.dll!_nh_malloc_dbg_impl(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine, int * errno_tmp) Line 239  C++
    msvcr110d.dll!_nh_malloc_dbg(unsigned int nSize, int nhFlag, int nBlockUse, const char * szFileName, int nLine) Line 302    C++
    msvcr110d.dll!malloc(unsigned int nSize) Line 56    C++
    msvcr110d.dll!operator new(unsigned int size) Line 59   C++
    App.exe!std::_Allocate<char>(unsigned int _Count, char * __formal) Line 28  C++
    App.exe!std::allocator<char>::allocate(unsigned int _Count) Line 591    C++
    App.exe!std::basic_stringbuf<char,std::char_traits<char>,std::allocator<char> >::overflow(int _Meta) Line 152   C++
    msvcp110d.dll!std::basic_streambuf<char,std::char_traits<char> >::sputc(char _Ch) Line 196  C++
    msvcp110d.dll!std::ostreambuf_iterator<char,std::char_traits<char> >::operator=(char _Right) Line 634   C++
    msvcp110d.dll!std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::_Put(std::ostreambuf_iterator<char,std::char_traits<char> > _Dest, const char * _Ptr, unsigned int _Count) Line 1553  C++
    msvcp110d.dll!std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::_Iput(std::ostreambuf_iterator<char,std::char_traits<char> > _Dest, std::ios_base & _Iosbase, char _Fill, char * _Buf, unsigned int _Count) Line 1544 C++
    msvcp110d.dll!std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::do_put(std::ostreambuf_iterator<char,std::char_traits<char> > _Dest, std::ios_base & _Iosbase, char _Fill, long _Val) Line 1216   C++
    msvcp110d.dll!std::num_put<char,std::ostreambuf_iterator<char,std::char_traits<char> > >::put(std::ostreambuf_iterator<char,std::char_traits<char> > _Dest, std::ios_base & _Iosbase, char _Fill, long _Val) Line 1137  C++
    msvcp110d.dll!std::basic_ostream<char,std::char_traits<char> >::operator<<(int _Val) Line 311   C++
    App.exe!TUtil::intToString(int val) Line 43 C++
    App.exe!TFontManager::getFont(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & filename, int size) Line 15  C++
    App.exe!TButton::draw() Line 55 C++
    App.exe!TWindow::draw() Line 203    C++
    App.exe!TGUIManager::drawObjects() Line 49  C++
    App.exe!TGameAppLayer::gameCycle() Line 456 C++
    App.exe!TGameAppLayer::mainLoop() Line 520  C++
    App.exe!wWinMain(HINSTANCE__ * hInstance, HINSTANCE__ * hPrevInstance, wchar_t * lpCmdLine, int nCmdShow) Line 36   C++
    App.exe!__tmainCRTStartup() Line 528    C
    App.exe!wWinMainCRTStartup() Line 377   C
    kernel32.dll!@BaseThreadInitThunk@12()  Unknown
    ntdll.dll!___RtlUserThreadStart@8() Unknown
    ntdll.dll!__RtlUserThreadStart@8()  Unknown

据我所知,我得到的错误是由访问(再次删除)已经释放的内存块引起的。尝试找出我的代码到底有什么问题已经是第三天了。在此期间,我发现了一些我已经修复的小内存泄漏,现在 Visual Leak Detector 告诉我它没有检测到任何泄漏。

但堆损坏的问题仍然存在。

在我的代码中使用“删除”运算符的每个地方,我首先检查指针是否不是nullptr。如果没有,我设置为nullptr

if(m_pVar != nullptr)
{
    delete m_pVar;
    m_pVar = nullptr;
}

所以看起来不止一次释放同一个内存块应该没有问题。

我试图从这个调用堆栈中找出一些东西,但我想向你寻求帮助。在调用堆栈中,string 分配似乎存在问题,但这究竟意味着什么?最后一个被调用的 MY 函数是 string TUtil::intToString(int val) Line 43,所以如果我向您展示该函数的主体可能会更容易:

std::string TUtil::intToString(int val)
{
    std::ostringstream s;
    s << val;                 // Here's line 43
    return s.str();
}

有时调用堆栈是不同的,所以string TUtil::intToString(int val) 函数甚至不存在其中,但它总是与strings 分配有关。

我希望我刚才所说的很清楚。如果您需要更多信息,请告诉我,我将在此问题的编辑中提供。

【问题讨论】:

  • 您是否在选择 Valgrind 的平台上?
  • 如果你在 linux 上工作,试着用 Valgrind 检查你的应用程序
  • 您是否定义了复制构造函数和赋值运算符或明确禁止复制具有成员 m_pVar 的类的实例?
  • 请注意:delete a nullptr 绝对安全。检查是不必要的
  • @KillianDS,感谢您提供的信息。不知道!

标签: c++ memory memory-leaks heap-corruption visual-leak-detector


【解决方案1】:

据我所知,我得到的错误是由访问(再次删除)已经释放的内存块引起的。

除非您知道某些事情但没有告诉我们,否则上述内容很可能是一个红鲱鱼。该错误可能意味着您正在通过悬空指针修改内存,或者由于缓冲区溢出。

如果您曾经复制过指针(显式地复制,或者没有定义复制构造函数/赋值操作符),在删除时设置 m_pVar = nullptr 将无法保证避免双重删除,更不用说其他类型的内存错误了。

如果您无法通过检查代码找到问题,最好的选择可能是 Valgrind 或 Purify 之类的工具。

【讨论】:

  • 感谢NPE的回答!抱歉回复晚了,但我仍在尝试根据大家给我的提示找到问题,感谢“应用程序验证器”和“调试诊断工具”程序,我终于找到了它。看来我一直在使用指向已释放内存块的指针。
【解决方案2】:

malloc 期间的崩溃是内存损坏的明确迹象,它可能是由于双重删除,也可能不是。损坏发生在您的代码的某些不同部分,不幸的是,这种影响在您失败的代码中蔓延开来,这绝对是无辜的。如果可能,尝试将您的应用程序移植到可以运行 valgrind 的系统中

【讨论】:

  • 感谢 Abhijit 的回答。问题是使用指向已释放内存块的指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-21
  • 2014-10-17
  • 2020-10-02
  • 2012-07-27
  • 2015-06-15
  • 1970-01-01
  • 2012-06-28
相关资源
最近更新 更多