2017-05-09 64 views
0

我使用OpenCV构建了一个多线程系统,该系统创建一些图像,将它们分配到一个矢量中,并将每个图像发送到不同的线程中。将OpenCV矩阵分配到数据结构中

这是它的样子:

std::vector<cv::Mat> images; 
for (int i = 0 ; i < 10 ; i++) { 
    images.push_back(cv::Mat(/* bla bla */)); 
    cv::Mat& mat = images.back(); 
    std::thread(some_function_name, &mat) 
} 
// Wait here for all threads to join (didn't show its code) 

看来,当线程获得的指针Mat对象,该对象Mat不存在了。是否有可能虽然它被立即分配给矢量,但是当循环结束时它实际上被销毁了,因为它被从堆栈上擦掉了?

回答

2

您的问题实际上是您在循环中调用push_back,这可能会导致重新分配。如果发生这种情况,底层数据将被复制,因此任何指针或引用都将失效。

要解决这个问题,一个办法是大小数组提前

std::vector<cv::Mat> images(10); 
for (int i = 0 ; i < 10 ; i++) { 
    images[i] = cv::Mat(/* bla bla */); 
    cv::Mat& mat = images.at(i); 
    std::thread(some_function_name, &mat) 
} 
// Wait here for all threads to join (didn't show its code) 
+0

你居然说发生不时原因吧'VECTOR'的自我扩展业务?所以如果我使用'std :: list'代替它,它会被阻止吗? – SomethingSomething

+1

@SomethingSomething [阅读此篇文章](https://stackoverflow.com/questions/17299951/c-vector-what-happens-whenever-it-expands-reallocate-on-stack)解释发生了什么“引擎盖下”当你添加元素到一个'std :: vector'。是的,你可以使用'std :: list'来避免这种情况,但这只是避免了这个问题,最好是理解*为什么*这是首先发生的,所以你理解不同标准库的行为容器。 – CoryKramer

+0

好,我明白了,我在“数据结构”课程中学习了使用分期分析,如果每次大小为(2^i)时扩展向量,那么平均复杂度为O(1) - 并且我理解它已完成在C++中使用“realloc()” - 当我编写代码时,我并没有深思。我在最后的评论中问了这个问题,以确保你的意思是针对特定的realloc – SomethingSomething