自从我编写C ++以来已经有一段时间了,所以我想确认一下我是否正确地做了这个:
vector<Mat>
VideoHash::dct3d(vector<Mat> cube)
{
vector<Mat> dctPlanes;
for (int k = 0; k < TEMPORAL_DIM; ++k)
{
Mat spatial;
Mat freq;
cube[k].convertTo(spatial, CV_64F);
dct(spatial, freq);
dctPlanes.push_back(freq);
}
// Do other stuff here
}
我有一个矩阵向量作为函数的输入。对于向量中的每个矩阵,我转换为不同的数据类型(double),对转换结果执行DCT,然后将DCT的结果存储在另一个向量中。
这看起来是对的吗?我对for循环中创建的矩阵有疑问。循环退出后,它们将超出范围。分配给堆栈中那些矩阵的内存会发生什么变化?循环后是否仍然可以访问该内存(例如,在“在此处执行其他操作”部分)。
答案 0 :(得分:5)
当你将矩阵推回到向量中时,它会被值复制到由向量分配的内存中。只要存在dctPlanes,其中的矩阵仍然存在。当然,你的临时(空间,频率)将超出每个循环迭代的范围。
编辑:为了解决优化问题,您可以考虑这样的事情:
VideoHash::dct3d(vector<Mat> & cube)
{
Mat spatial;
vector<Mat> dctPlanes;
dctPlanes.resize(TEMPORAL_DIM);
for (int k = 0; k < TEMPORAL_DIM; ++k)
{
cube[k].convertTo(spatial, CV_64F);
dct(spatial, dctPlanes[k]);
}
// Do other stuff here
}
它并不完美,因为理想情况下,当你调整向量大小时,你需要避免调用所有这些构造函数的成本 - 并且有很多方法 - 但与原始代码相比,这将获得不错的收益。
答案 1 :(得分:0)
dctPlanes.push_back(freq)
将复制临时矩阵freq
到容器中。如果Mat
具有正确的复制构造函数,您仍然可以通过容器访问数据。显然,freq
和spatial
本身在每次迭代结束时都会被销毁,无法直接访问。
如果关注效率,您可能需要考虑为Mat实现C ++ 11移动构造函数,然后使用:
dctPlanes.push_back( std::move(freq) )
在此行之后,即使在循环范围结束之前,freq
本身也会失效 - 因为它已移动到容器中。