统一初始化导致C ++中的运行时错误

时间:2018-12-11 15:43:30

标签: c++ opencv uniform-initialization

我是统一初始化的忠实拥护者,在大多数情况下,当我想构造初始化变量时,都使用它。最近,我在构造cv::Mat类型的变量时遇到了奇怪的错误。

cv::Mat lookUpTable( 1, 256, CV_8U );
uchar* p = lookUpTable.ptr();

for( int i = 0; i < 256; ++i )
{
    p[i] = cv::saturate_cast<uchar>( pow( i / 255.0, gamma ) * 255.0 );
}

如果使用统一初始化,则此实现效果很好

cv::Mat lookUpTable{ 1, 256, CV_8U };

出现以下错误

  

malloc_consolidate():无效的块大小

我仍然不太确定会发生什么。是否使用了不同的构造函数(超出预期)?有人可以进一步解释吗?

2 个答案:

答案 0 :(得分:8)

cv::Mat lookUpTable{ 1, 256, CV_8U }调用了与cv::Mat lookUpTable( 1, 256, CV_8U )不同的构造函数。 cv::Mat lookUpTable{ 1, 256, CV_8U } direct-list-initialization ,并且由于cv::Mat具有接受std::initlizer_list的构造函数,因此该构造函数将被调用,而不是第一个调用的3参数做。这意味着您有一个包含元素{ 1, 256, CV_8U }的矩阵,而不是256个元素的矩阵。

Nicolai Josuttis在CppCon2018上对统一初始化的“均匀性”进行了非常好的演讲:https://www.youtube.com/watch?v=7DTlWPgX6zs

答案 1 :(得分:4)

使用{...}构造一个对象称为“列表初始化”

cv::Mat提供了一个使用std::initializer_list的构造函数: https://github.com/opencv/opencv/blob/master/modules/core/include/opencv2/core/mat.hpp#L1007

超载分辨率中有一个special rule ,如果列表初始化始终优先考虑使用std::initializer_list的构造函数使用>,而不考虑是否存在其他可能需要较少隐式转换的构造函数。

呼叫cv::Mat(...)cv::Mat{...}完全不同。


对此,我的思维模型是:如果要构造的对象是容器,则{...}的行为可能与(...)不同,因此,请务必小心。否则,请选择{...}