【问题标题】:C++ - vector <class> and std::bad_allocC++ - 向量 <class> 和 std::bad_alloc
【发布时间】:2023-03-04 02:47:01
【问题描述】:

我正在将一个程序从 matlab 代码转换为 C++,我必须在 Linux 上使用 opencv 库(gcc 版本 4.9.2)

所以我正在尝试翻译这行matlab代码:

repeatedMat = repmat(originalMat,[1 1 k]); 

我最后写的代码是这样的:

void repeat(cv::Mat img, std::vector <cv::Mat> &output, uint32_t nx, uint32_t ny, uint32_t z)
{
    cv::Mat tmpMat = cv::repeat(img, nx, ny);
    output = std::vector <Mat> (z);

    for (uint32_t i = 0; i < output.size(); i++)
        output.insert(output.end(), tmpMat);
}

问题是我总是遇到 std::bad_alloc 错误

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted

我不知道确切原因,但我正在考虑一些内存泄漏.. 有没有更好的(和有效的)方法来做到这一点?

【问题讨论】:

  • 你所有的代码都应该减少到vector &lt;Mat&gt; output(z, img);
  • 除此之外,如果你想在vector的末尾添加一个元素,你应该使用push_back方法。
  • 每次循环迭代,output 向量都会增长,所以循环永远到达终点......直到程序内存不足。跨度>

标签: c++ matlab opencv c++11


【解决方案1】:

在 C++ 中,for 循环的条件在每次迭代中都会被评估,因此如果在向量末尾添加一个新元素,它会增长 1,因此在下一次迭代中计数器 i 将达不到。它应该是这样的:

for (uint32_t i = 0; i < z; i++)
    output.insert(output.end(), tmpMat);

但正如 rahnema1 在 cmets 中所说,您不需要这样做。您可以使用同一元素的 z 副本创建一个向量,而无需复制它们:

output = std::vector <Mat> (z, tmpMat);

另外,由于您已将您的问题标记为“c++11”,所以我再提出一个额外的建议:按值返回向量,编译器将避免复制。

std::vector <cv::Mat> repeat(cv::Mat img, uint32_t nx, uint32_t ny, uint32_t z)
{
    return std::vector<cv::Mat>(z, cv::repeat(img, nx, ny));
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-06
    • 2014-05-29
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    相关资源
    最近更新 更多