boost circular buffer in stl vector crashes in release

问题内容:

I have a class where I define a circular buffer like so:

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

I then create a stl vector of type cTest

std::vector<cTest> vC;

Afterwards I try to fill the vector like this:

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

While this works in Debug mode, in Release, it crashes (sometimes, when I run with from Visual Studio, I get a Heap Corruption message). The boost documentation mentions, that in Debug mode, the uninitialized memory is filled with ‘0xcc’. I assume, the error I get, has its root in uninitialized memory. But I am not really sure, how to fix this problem.

If I use pointers, it seems to work:

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

But I still do not know, what the problem with the first version is. If anyone does know, I’d appreciate the help.

问题评论:

    
1  
I bet you’re forgetting about iterator/reference invalidation. So the problem is not with the code shown
    
I cannot post a working example from the code because it’s burried within a library that is called by a gui. However, the code I posted is directly called in the constructor of the class – so there is not much going on before that. Creating the code on it’s own like this pastebin.com/6ccPjuzZ works without a crash.
– Lgum
2 hours ago

答案:

答案1:

I bet you’re forgetting about iterator/reference invalidation. So the problem is not with the code shown.

This makes sense since you report that pointers seem to work: the pointers stay the same even if push_back causes reallocation.

Simply don’t hold on to references/iterators to vector elements when you don’t know that they’re going to stay valid.

If your vector has a known maximum size, you could “cheat” by reserving the capacity ahead of time:

static constexpr size_t MAX_BUFFERS = 100;

std::vector<cTest> vC;
vC.reserver(MAX_BUFFERS); // never more

And then perhaps guard the invariant:

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

答案评论:

    
I do know the capacity beforehand – however, reserving it, does not change the crash behaviour. Using a ‘debugging’ help, by printing out infos after each ‘action’ reveals, that the first loop seems to work – but once the second loop starts, it crashes. I.e. qDebug() << “Creating new object\n”; etc. prints all the lines out for the first loop. The second loop then crashes. Can it be that the object goes somehow out of scope?
– Lgum
1 hour ago
    
Come on. There is no second loop. We’re not psychics. Of you want help, improve the question. Yes lifetime issues are almost certainly the culprit. I don’t see enough reason to narrow my diagnosis down until we see a self contained example.

原文地址:

https://stackoverflow.com/questions/47753816/boost-circular-buffer-in-stl-vector-crashes-in-release

添加评论