试图将元素添加到现有std :: vector的堆损坏

试图将元素添加到现有std :: vector的堆损坏

问题描述:

我有一个std::vector,其中包含类BoundingBox(std::vector<BoundingBox>,我称为BB_Array)的元素. 首先,我使用将在此处简化的函数创建此向量:

I have an std::vector containing elements of class BoundingBox (std::vector<BoundingBox>, which I call BB_Array). First, i create this vector using a function that I will simplify here:

BB_Array* Detector::generateCandidateRegions(BB_Array* candidates){
    BB_Array* result = new BB_Array(); // without new here, i get segmentation fault
    BB_Array tempResult;

    // apply tests to candidates and add the good ones to tempResult ... 
    // ... using tempResult.push_back((*candidates)[i]);

    for (int i=0; i < tempResult.size(); i++){
        // apply more tests to tempResult[i] and, if necessary, add it...
        // ... using result->push_back(maxCandidate); 
    }

    return result;
}

此功能有效,并且根据valgrind,不会发生内存泄漏. 现在,该功能需要应用一次(以提高性能),我需要一个向其添加元素的功能.这就是我遇到的问题.我现在的操作方式是:

This function works and there is no memory leak according to valgrind. Now, that function needs to be applied once (for performance) and I need a function to add elements to it. This is where I'm having problems. The way I'm doing it now is:

BB_Array* Detector::addCandidateRegions(BB_Array* candidates) {
    BB_Array* result = new BB_Array();
    BB_Array sparseDetections;

    // apply tests and add stuff to sparseDetections using... 
    // ... sparseDetections.push_back((*candidates)[i]);

    for (int i=0; i < sparseDetections.size(); i++){
        // add things to result using result->push_back()
    }

    return result;
}

第二个功能给了我需要添加到之前创建的向量中的候选对象:

This second function gave me the candidates I need to add to the vector created before:

BB_Array *newCandidates = addCandidateRegions(...);
if (newCandidates->size() > 0){
   denseCandidates->insert(denseCandidates->end(), newCandidates->begin(), newCandidates->end());
   delete newCandidates;
}

现在,这导致堆损坏,并且在出现500张图像后程序崩溃.那我在做什么错?有更好的方法吗?

Now, this is causing heap corruption and the program crashes after something like 500 images. So what am I doing wrong? Is there a better way of doing this?

我还有一个函数,可以从向量中删除元素,但是我认为一旦完成加法部分就可以弄清楚.

I also have a function to remove elements from the vector afterwards, but I think I can figure it out once I get the adding part done.

忘记输入错误消息:

*** Error in `./C_Arnoud_Calibrated_Detector': malloc(): smallbin double linked list corrupted: 0x0000000001f4eed0 ***
Aborted (core dumped)

并非每次都在相同的迭代中发生,有时我会遇到分段错误.

doesn't happen at the same iteraction every time and, sometimes, I get a segmentation fault instead.

我今天修复了它.没有更多的堆问题.我可能很累,并在一种特定情况下使用了错误的索引,因此在成千上万次迭代中,有时会发生意想不到的事情,这破坏了一切.感谢大家的建议,如果您使用对象检测器,现在可以放心使用=).
https://github.com/CArnoud/C_Arnoud_Calibrated_Detector

EDIT 2: I fixed it today. No more heap problems. I was probably tired and used the wrong index in one specific scenario, so out of thousands of iteractions sometimes unexpected things happened and it broke everything. Thanks everybody for the suggestions and, if you use an object detector, it is now safe to use =).
https://github.com/CArnoud/C_Arnoud_Calibrated_Detector

首先,您是否使用比您更早的编译器?

First off, do you use a compiler that is older than you ?

是->停止这样做.你为什么这么讨厌自己?

Yes -> Stop doing that. Why are you hating yourself so much ?

否->好消息,您的教授教给您"有关C ++的一切都是对与错.编译器非常擅长返回值优化.使您的函数返回值,它们将被移动而不被复制,这实际上是免费的,并停止应用程序代码中的这种新的/删除的/原始的指针疯狂行为.

No -> Good news, everything your professors have "taught" you about C++ is wrong and false. Compilers are very good at return value optimization. Make your functions return values, they will be moved and not copied, which is essentially free, and stop this new/delete/raw pointer madness in application code.

BB_Array Detector::generateCandidateRegions(BB_Array& candidates){
    BB_Array result; // Use values.
    BB_Array tempResult;

    // Do whatever the heck you want.

    for (int i=0; i < tempResult.size(); i++){
        // apply more tests to tempResult[i] and, if necessary, add it...
        // ... using result.push_back(maxCandidate); 
    }

    return result;
}

BB_Array newCandidates = addCandidateRegions(...);
if (newCandidates.size() > 0){
   denseCandidates.insert(denseCandidates.end(), newCandidates.begin(),
                          newCandidates.end());
}

轻松的内存管理,轻松的生活.

Easy memory management, easy life.