【问题标题】:Heap Corruption trying to add elements to existing std::vector堆损坏试图将元素添加到现有的 std::vector
【发布时间】:2015-05-16 23:01:26
【问题描述】:

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

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 没有内存泄漏。 现在,该函数需要应用一次(为了提高性能),我需要一个函数来添加元素。这就是我遇到问题的地方。我现在的做法是:

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;
}

第二个函数为我提供了我需要添加到之前创建的向量的候选对象:

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

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

我还有一个函数可以在之后从向量中删除元素,但我想我可以在完成添加部分后弄清楚。

编辑:忘记输入错误信息:

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

不会每次都在同一个迭代中发生,有时我会遇到分段错误。

编辑 2:我今天修好了。没有更多的堆问题。我可能很累并且在一个特定的场景中使用了错误的索引,所以在成千上万的迭代中有时会发生意想不到的事情并且它破坏了一切。感谢大家的建议,如果您使用对象检测器,现在可以安全使用 =)。
https://github.com/CArnoud/C_Arnoud_Calibrated_Detector

【问题讨论】:

  • 停止使用 new/delete。这里没有必要。通过 (const) 引用将向量传递给您的函数并按值返回它们。
  • 您可以尝试提取并发布行为不端的最小编译示例吗?在这个抽象级别上,我没有看到任何导致内存问题的东西。 (如果在最后一个示例中有点可疑,请删除内部,但在示例周围使用正确的代码,它会正常工作)。
  • @DDrmmr 如果我拿走新的,我会收到分段错误错误
  • @Charles:不要只是拿走new——完全改变API和实现,所以这一切都是在价值和参考方面。
  • 你的 BB_Array 析构函数会删除任何内存吗?如果你复制一个,它会复制内部指针吗?这是一个常见但灾难性的组合。

标签: c++ vector heap-corruption


【解决方案1】:

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

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

否 -> 好消息,你的教授“教”给你的关于 C++ 的一切都是错误和错误的。编译器非常擅长返回值优化。让你的函数返回值,它们将被移动而不是复制,这基本上是免费的,并停止在应用程序代码中这种新/删除/原始指针的疯狂。

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());
}

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

【讨论】:

  • 哦,我该如何调用 generateCandidateRegions 函数?
  • 很遗憾,它并没有解决我的问题。但这是使代码更清晰的好建议。如果我愿意,我愿意。
  • @Charles Arnoud 你会用一个值调用 generateCandidateRegions。你能发布一个更完整的代码示例吗?或者你有指向你的 git 存储库的链接或类似的东西吗?
  • 仓库是:github.com/CArnoud/C_Arnoud_Calibrated_Detector,问题出在Detector.cpp文件中。但是,老实说,这是一个非常长的文件,调试它可能需要很长时间。
  • 我不知道 valgrind 可用于任何比 OP 更早的编译器!
猜你喜欢
  • 2015-10-03
  • 2022-01-19
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
  • 2011-09-04
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
相关资源
最近更新 更多