昨天我问了一个有关此问题的问题,但我无法提供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;
};
在 anotherCPP.cpp
#include "Header1.h"
程序退出main()时,它会破坏所有静态对象并引发异常。
如果这不会崩溃,则可能是在您的系统上,编译器/链接器优化了一些代码,因此您可以尝试使 main.cpp 和 anotherCPP.cpp 起作用的东西。在 otherCPP.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
在我的项目中,我从上面逐步完成了std :: list清除循环,我记下了“ this”指针地址。我逐步完成了循环,因为它释放了列表中的节点。然后返回免费的其他std :: lists,包括在std :: unordered_map中(因为它们从外观上也使用std :: lists)。最后,当抛出读取访问异常并且 _Pnode 是无效的指针地址时,我注意到在清除 std :: list时,“ this”指针地址与“ this”指针地址相同
我希望有人能重现此内容,如果是错误或我做错了什么,我不确定这是什么。同样,这对我来说是32位和64位的,但仅在调试模式下会发生,因为我提供的节点释放循环在宏下:
#if _ITERATOR_DEBUG_LEVEL == 2
答案 0 :(得分:2)
此问题已作为错误here提交,标题为“在调试模式下内联静态数据成员的多次初始化”。
这是在Visual Studio 2017版本15.7中发现的。
VS编译器团队已经接受了这一点,并在即将发布的版本中解决了该问题。