c++ - 为什么更改 Visual Studio 版本后我的函数会崩溃?
问题描述
我有一个用 Visual Studio 2010 编写的 C++ 中的旧 32 位 MFC 应用程序。它运行没有问题。现在我不得不升级到 Visual Studio 2017,当我单击树视图窗口时它经常崩溃。我有一个 dmp 文件,当我打开它时,我看到它在这里崩溃:
BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
{
ENSURE(this != NULL);
// it better be in valid memory, at least for CObject size
ASSERT(AfxIsValidAddress(this, sizeof(CObject)));
// simple SI case
CRuntimeClass* pClassThis = GetRuntimeClass(); //---->HERE Crash
ENSURE(pClassThis);
return pClassThis->IsDerivedFrom(pClass);
}
当我返回通话清单时,我会在这里结束:
//m_pTheModel is initialized with NULL
if (bValidValue == true)
m_pTheModel = GetModel((WORD)lHint);
if (m_pTheModel == NULL || !AfxIsValidAddress(m_pTheModel, sizeof(m_pTheModel)))
{
lock.Unlock();
return;
}
try
{
if ((m_pTheModel->IsKindOf(RUNTIME_CLASS(CMyClassModel))))
...
}
catch (...)
{
}
m_pTheModel 不是 NULL,但是当我查看调试器中的值时,对于某些值,内存不可读。
问题可能是什么?使用旧版本的视觉工作室我没有这个问题。我只重新编译了这个项目,我不得不将目标操作系统设置为 Windows XP。
错误消息是“线程试图读取或写入它没有适当访问权限的虚拟地址。”</p>
我也不明白为什么我不能用我的 try-catch 来捕捉这个访问冲突。
更新: 我找到了原因。这是一个覆盖我的指针的 strcpy。
解决方案
的使用AfxIsValidAddress
非常令人担忧。
测试任何内存地址以确保它完全包含在程序的内存空间中。
更糟糕的是,它只适用于调试版本。
在非调试版本中,如果 lp 不为 NULL,则为非零;否则为 0。
这并不能保证它是你想要的。如果你删除一个对象,内存可能仍在应用程序中准备好被重用,而不是返回给操作系统,并且类似的东西AfxIsValidAddress
将返回 true。更糟糕的是,当您的分配器确实重用该内存时,它仍然会返回 true,而指针现在实际上指向的是一些完全不同的未知对象,从而导致堆损坏。
这适用于所有类似的功能,例如IsBadReadPtr
. Raymond Chen 有一篇 Microsoft 博客文章IsBadXxxPtr 真的应该被称为 CrashProgramRandomly。
您可能必须在 IDE 中对此进行调试并找到一个特定问题,这几乎可以肯定是免费问题后的使用,或者是覆盖对象的程序中其他地方的更严重问题。您可以直接在 IDE 中生成它而不是获取转储文件吗?
我也不明白为什么我不能用我的 try-catch 来捕捉这个访问冲突
各种平台上的访问冲突等都不是 C++ 异常。而且由于它们通常仅在程序内存损坏后发生,因此基本上无法恢复。通常有一些特定于平台的方法可以与它们进行交互。
推荐阅读
- asp.net-core - 在 Aspnet core 3.0 中使用 ElmahCore 在全球范围内捕获异常?
- javascript - 在d3中从x轴添加网格线到线高
- angular - 使用 *ngIf 的 AGM 地图
- php - Chromedriver 重定向到 chrome-error://chromewebdata/ 并显示一个空白屏幕,即使请求一直到脚本末尾也是如此
- angular - 拖放表单元素
- javascript - 我们是否有任何带有 html 的 javascript 功能,我们可以在 Chrome 浏览器中自动打开开发者工具?
- c# - 尝试连接到已删除的 cosmos db 时,有什么方法可以将错误记录限制到 Appinsight
- sas - 通过 OBC 将 SAS 连接到 Oracle 数据库时为空库
- regular-language - 你如何在抽引引理中划分字符串?
- microservices - 在 AWS 上部署 Nestjs 微服务