我有一个简单的Floodfill函数,除了它在运行时由于过多的分配而崩溃时。
#include <vector>
cv::Mat fillLayer(cv::Mat filledEdge, int y, int x, int oldColor, float newColor){
cv::Size shape = filledEdge.size();
int h = shape.height;
int w = shape.width;
std::vector<int> theStackx = {x};
std::vector<int> theStacky = {y};
while (theStacky.size() > 0){
y = theStacky.back();
x = theStackx.back();
theStacky.pop_back();
theStackx.pop_back();
if (x == w){
continue;
}
if (x == -1){
continue;
}
if (y == -1){
continue;
}
if (y == h){
continue;
}
if (filledEdge.at<float>(y, x) != oldColor){
continue;
}
filledEdge.at<float>(y, x) = newColor;
//up
theStacky.push_back(y + 1);
theStackx.push_back(x);
//down
theStacky.push_back(y - 1);
theStackx.push_back(x);
//right
theStacky.push_back(y);
theStackx.push_back(x + 1);
//left
theStacky.push_back(y);
theStackx.push_back(x - 1);
}
return filledEdge;
}
通过Floodfill运行的功能是fillSurface
。它遍历了Mat中的所有像素,并为每个泛洪填充了不同的颜色
fillSurface(cv::Mat filledEdge, int oldColor) {
std::vector<float> layers; //list all the different colors in mat
cv::Size shape = filledEdge.size();
int h = shape.height;
int w = shape.width;
float newColor;
// run through all the pixels in Mat
for(int y = 0; y!= h; y++){
for(int x = 0; x!= w; x++){
// only run floodfill if current pixel is oldColor
if (filledEdge.at<float>(y, x) == oldColor){
//newColor is random float to fill in to floodfill
newColor = static_cast <float> ((rand()) / (static_cast <float> (RAND_MAX/253)) + 1);
// add newColor to list of layers
layers.push_back(newColor);
//run flood fill replacing old color with new color
filledEdge = fillLayer(filledEdge, y, x, oldColor, newColor);
}
}
}
}
这是我收到的错误:
Incorrect checksum for freed object 0x7fea0d89dc00: probably modified after being freed.
我已经完成的调试工作已经在malloc_error_break()上设置了一个断点,以查看我到底在哪里得到了中断。确实导致了洪水填充功能。
我想知道是否有任何解决办法。如果没有,最好的选择是什么?
答案 0 :(得分:1)
没有MCVE,我无法直接重现您的问题,而且我自己也不认识简历。但是我可以做出一些可能会有所帮助的猜测。
运行时错误指出“释放对象的校验和不正确...:释放后可能已修改。”
第一个给您的提示是,这样的堆检查通常仅在堆操作发生时才发生,而不是在发生损坏时才进行。您的代码中没有任何显式的堆操作(例如new
或delete
)。此处的堆使用来自标准库(vector
)和cv(Mat
)的经过充分证明和测试的数据结构。
第二个提示是probably modified after being freed
,但这是不完整的-另一种可能是某些代码超出了其范围-缓冲区溢出或不正确的数组索引或类似的东西。
最后一点将我们带到Mat类的CV文档,该文档在任何地方都没有提到如果错误地为Mat编制索引会发生什么情况。 确实发出警告,以确保您使用正确的元素类型进行访问,否则可能会出错。这些东西可能会非常有力地暗示,如果您错误地访问Mat,可能会发生不好的事情。就像,如果您正在写作,也许是内存损坏。
这些事情以及上面我对声明变量h
和w
但未使用它们的评论-那么您认为您将使用h
和w
的目的-应该使您有很长的路要走,弄清楚堆是如何损坏的,直到运行时系统抱怨它。
扰流板警报(为获得最佳效果,在解决问题后,仅在 之后阅读):
在
Mat
的边界之外写,因为您从不检查索引的边界以防止它们超出限制,而且显然Mat::at
也没有检查(至少,文档没有这样做)没错-您可以通过实验验证这一点。