在STL矢量中的增强圆形缓冲液在发行版中崩溃

boost circular buffer in stl vector crashes in release

本文关键字:崩溃 缓冲 STL 增强      更新时间:2023-10-16

我有一个类,我定义了这样的圆形缓冲区:

class cTest
{
    public:
    boost::circular_buffer<std::vector<std::pair<double, double>>> circDat;
       cTest() : circDat(1000)
       {
       }
};

i然后创建一个类型ctest

的STL向量
std::vector<cTest> vC;

之后,我尝试填充矢量:

for (unsigned int i = 0; i < 4; ++i)
{
    cTest obj;
    vC.push_back(obj);
}

虽然在调试模式下工作,但在发行版中,它会崩溃(有时,当我从Visual Studio中运行时,我会收到一个堆的损坏消息)。Boost文档提到,在调试模式下,非初始化的内存充满了" 0xcc"。我认为,我得到的错误在非初始化的内存中具有根源。但是我不确定,如何解决此问题。

如果我使用指针,它似乎有效:

std::vector<cTest*> vC;
for (unsigned int i = 0; i < 4; ++i)
{       
    cTest* obj = new cTest;
    vC.push_back(obj);
}

,但我仍然不知道,第一个版本的问题是什么。如果有人知道,我会感谢您的帮助。

编辑:

我试图创建一个最小的,可再现的代码,但失败了。它似乎也随机崩溃,与添加/删除的行没有真正的关联。然后,我偶然发现了Visual Studio 2015中的/GL标志。

关闭/gl标志后(在GUI项目中 - 在可以保留的图书馆项目中),我一直无法重新创建崩溃。我不知道,这是否真的是一个解决方案。但是,Visual Studio 2010中似乎存在类似的问题:最终撞车 - 使用 - openmp-x64-

edit2:

我设法将一个最小的工作示例汇总在一起。代码可以在此处下载:

https://github.com/davidmarianovak/crashtest

您需要Boost(我使用1.60)和QT5(我使用了5.6.3)。在版本中构建goacquire(/gl在Visual Studio中活跃)。之后,在发行版中构建gogui(激活/gl并使用'标准'进行链接时间代码生成)。构建它后,运行它并应崩溃。

可以通过在" gointerface.hpp"第22行中更改此崩溃:

void fillGraphicsViews(std::vector<cSensorConstruct> vSens);

to

void fillGraphicsViews(std::vector<cSensorConstruct> &vSens);

,但我并不真正相信这是问题。谁能告诉我,我在做什么错?我正在使用Visual Studio 2015。

我敢打赌,您忘记了迭代器/参考无效。因此,问题是不是带有代码。

  • 迭代器无效规则

这是有道理的,因为您报告指针似乎有效:即使push_back导致重新分配,指针也保持不变。

当您不知道它们将保持有效时,根本不会坚持参考/迭代器。

如果您的向量具有已知最大尺寸,则可以通过提前保留容量来"作弊":

static constexpr size_t MAX_BUFFERS = 100;
std::vector<cTest> vC;
vC.reserver(MAX_BUFFERS); // never more

,然后也许会守护不变的:

assert(vC.size() < MAX_BUFFERS);
vC.push_back(obj);