C++ 返回对象Mat时为什么会发生堆损坏?

C++ 返回对象Mat时为什么会发生堆损坏?,c++,visual-c++,opencv,heap-corruption,C++,Visual C++,Opencv,Heap Corruption,我不明白为什么这个程序会出现损坏的堆错误我正在使用OpenCV作为类Mat: 及 我读到,返回一个对象的拷贝在C++中比引用更优雅。所以我想知道是什么问题 编辑:VisualStudio在->decodevect处中断,但仅当我返回对象而不是引用时才会发生 编辑2: 我编辑了代码以反映整个程序。我认为问题来自于共享对象a,它同时被复制和修改。我将使用互斥锁查看问题是否仍然存在。您使用互斥锁时没有初始化它 int main() { A* a; vector<uchar>

我不明白为什么这个程序会出现损坏的堆错误我正在使用OpenCV作为类Mat:

<>我读到,返回一个对象的拷贝在C++中比引用更优雅。所以我想知道是什么问题

编辑:VisualStudio在->decodevect处中断,但仅当我返回对象而不是引用时才会发生

编辑2: 我编辑了代码以反映整个程序。我认为问题来自于共享对象a,它同时被复制和修改。我将使用互斥锁查看问题是否仍然存在。

您使用互斥锁时没有初始化它

int main() {
    A* a;
    vector<uchar> vect;
    while(1) {
        // get the vector of data
        a->decode(vect);
欢迎来到未定义的行为,人口:你

初始化a以获得更好的结果。

使用a时不初始化它

int main() {
    A* a;
    vector<uchar> vect;
    while(1) {
        // get the vector of data
        a->decode(vect);
欢迎来到未定义的行为,人口:你


初始化a以获得更好的结果。

那么这就是线程同步问题,正如您自己所建议的那样。图像在无限的while循环中不断被填充。在它的中间,你试图复制它。灾难的秘诀。在每次迭代中,您都需要在DoThreadProc中的该循环内设置一个写锁。然后你需要在你的get_图像中设置一个读锁。您需要使用一个读/写锁库,它不会使读卡器饿死

或者,您可以使用互斥体/关键部分。无论是写循环,还是读get_映像,在他们工作时都只获得对映像的独占访问权


不过我很好奇——你的线程过程是在无限循环中解码东西。你想在里面干什么?在阅读时,你希望看到什么样的图像?循环迭代中该时间点有图像吗?

那么这就是线程同步问题,正如您自己所建议的。图像在无限的while循环中不断被填充。在它的中间,你试图复制它。灾难的秘诀。在每次迭代中,您都需要在DoThreadProc中的该循环内设置一个写锁。然后你需要在你的get_图像中设置一个读锁。您需要使用一个读/写锁库,它不会使读卡器饿死

或者,您可以使用互斥体/关键部分。无论是写循环,还是读get_映像,在他们工作时都只获得对映像的独占访问权

不过我很好奇——你的线程过程是在无限循环中解码东西。你想在里面干什么?在阅读时,你希望看到什么样的图像?循环迭代中该时间点的任何映像?

cv::Mat的复制构造函数不会创建映像的深度副本。它只是创建对原始Mat的引用并增加其引用计数。 在类的以下函数中,return语句调用copy构造函数,返回对原始映像的引用,这可能是堆损坏的原因:

Mat get_image(){ return image; }
您应该返回图像的深度副本,如下所示,以便不会意外修改原始图像

Mat get_image(){ return image.clone(); }
cv::Mat的复制构造函数不会创建映像的深度副本。它只是创建对原始Mat的引用并增加其引用计数。 在类的以下函数中,return语句调用copy构造函数,返回对原始映像的引用,这可能是堆损坏的原因:

Mat get_image(){ return image; }
您应该返回图像的深度副本,如下所示,以便不会意外修改原始图像

Mat get_image(){ return image.clone(); }

我的错,我现在就改正。问题是为什么我会因为返回一个对象而得到堆损坏。我的错,我现在就纠正它。问题是为什么我会因为返回一个对象而导致堆损坏。请按引用或常量引用获取向量。@Ajay我仍然有错误。按引用传递避免复制,但在解码结束时它会被删除,对吗?这不是答案,而是建议。@Ajay好的,我编辑了代码以考虑您的建议。在使用空向量调用decode后,imdecode是否返回空矩阵?按引用获取向量或常量引用。@Ajay我仍然有错误。通过引用传递避免复制,但它在解码结束时被删除,对吗?这不是答案,而是建议。@Ajay ok,我编辑了我的代码以考虑您的建议。imdecode在使用空向量调用decode后是否返回空矩阵?我想使用c++11中的互斥体,但它未在vs2010中实现。。。也许我会使用boost,实际上,我获取数据并初始化向量的部分是网络部分。我有UI的主线程和网络的主线程。我有几种解决方案,比如使用异步或非阻塞套接字。我不确定我用的是不是最好的。互斥从什么时候开始从windows开发中消失了?尽管VS的最新版本可能会使使用本机win库更加困难,但它们仍然存在。正如我所说的,这是必然的
st使用实现读写锁的类。写windows编程书籍的杰弗里·里克特(Jeffery Richter)已经有一本多年了。我尝试使用互斥锁,但仍然存在问题。@sgar91在评论中指出的是有效的。我正在等待他的进一步解释。我想使用c++11中的互斥,但它没有在vs2010中实现。。。也许我会使用boost,实际上,我获取数据并初始化向量的部分是网络部分。我有UI的主线程和网络的主线程。我有几种解决方案,比如使用异步或非阻塞套接字。我不确定我用的是不是最好的。互斥从什么时候开始从windows开发中消失了?尽管VS的最新版本可能会使使用本机win库更加困难,但它们仍然存在。正如我所说的,最好使用一个实现读写锁的类。写windows编程书籍的杰弗里·里克特(Jeffery Richter)已经有一本多年了。我尝试使用互斥锁,但仍然存在问题。@sgar91在评论中指出的是有效的。我在等他的解释。