【发布时间】: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