【发布时间】:2018-10-15 04:04:53
【问题描述】:
昨天我问了一个关于这个问题的问题,但我无法给出一个 MVCE。我已经设法用一个简单的程序重现了这一点。问题在于使用 std::list 作为类中的静态内联声明。 Microsoft Visual Studio 确实支持这个新的 C++17 功能。截至 3 月,它有一些错误,但据我所知,它们已经得到修复。以下是如何解决此问题的说明,这发生在调试模式下。
在main.cpp
#include <iostream>
#include "header1.h"
int main()
{
return 0;
}
在 header1.h:
#include <list>
struct Boo
{
static inline std::list<int> mylist;
};
在另一个CPP.cpp
#include "Header1.h"
当程序退出 main() 时,它会销毁所有静态对象并抛出异常。
如果这没有崩溃,可能是您的系统上的编译器/链接器优化了一些代码,所以您可以尝试让 main.cpp 和 anotherCPP.cpp 做某物。在另一个CPP.cpp中:
#include <iostream>
#include "Header1.h"
void aFunction()
{
std::cout << Boo::mylist.size();
}
并制作 main.cpp:
#include <iostream>
#include "Header1.h"
void aFunction();
int main()
{
std::cout << Boo::mylist.size();
afunction();
return 0;
}
当程序退出时,当 std::list 被清除时,我在这里得到一个异常。这是崩溃的 Visual Studio 调试代码:
for (_Nodeptr _Pnext; _Pnode != this->_Myhead(); _Pnode = _Pnext)
{ // delete an element
_Pnext = _Pnode->_Next; // Here: Exception thrown:
// read access violation.
// _Pnode was 0xFFFFFFFFFFFFFFFF.
this->_Freenode(_Pnode);
}
仅当我在类中声明静态内联 std::list mylist 时才会发生这种情况。如果我在我的类中将其声明为 static std::list mylist ,然后在一个 .cpp 中将其单独定义为 std::list Boo::mylist; 它工作正常。当我声明 std::list 静态内联并将该类的标头包含在两个 .cpp 文件中时,就会出现此问题。
在我的项目中,我从上面逐步完成了 std::list clear 循环,我记下了“this”指针地址。我逐步完成了循环,因为它释放了我列表中的节点。然后它回来释放其他 std::lists,包括在 std::unordered_map 中(因为他们也使用 std::lists 从它的外观)。最后,当抛出读访问异常并且 _Pnode 是一个无效的指针地址时,我注意到“this”指针地址与清除 std::list 时的“this”指针地址相同 mylist,这让我觉得它试图删除它两次,并且可能是它崩溃的原因。
我希望有人可以重现这个,我不确定这是什么,如果它是一个错误或我做错了什么。这也发生在我的 32 位和 64 位中,但仅限于调试模式,因为我提供的节点释放循环位于宏下:
#if _ITERATOR_DEBUG_LEVEL == 2
【问题讨论】:
-
看起来这应该是一个 MSVC 错误报告,而不是一个 SO 问题
-
天真地假设 VS 中的所有错误自 3 月以来都已修复。
-
" 但仅在调试模式下" 我很确定这也发生在发行版中,但它是静默失败。
-
你应该。在这种特殊情况下,它最多可以与另一个错误报告合并。您似乎很好地掌握了内联变量,无需自我怀疑。
标签: c++ exception inline c++17