提升功能的怪异行为

时间:2018-07-03 19:09:30

标签: c++ boost eigen

如果我注释掉构造函数的第一行,我的以下代码将出错。返回错误是:

libc++abi.dylib: terminating with uncaught exception of type boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<std::overflow_error> >: Error in function boost::math::cyl_bessel_k<double>(double,double): numeric overflow
Abort trap: 6

但是,如果我在构造函数中输出了一些内容(例如,取消第一行注释),那我的程序就可以正常工作了。

GP::GP(const Training_set& _sample, Eigen::VectorXd& param, 
                const std::string& which_kernel) : sample(_sample)
{
//      std::cout << "WORKS" << std::endl;
        if (which_kernel == "Matern") {
                std::cout << "Matern kernel is used!" << std::endl;
                Kernel_Matern matern(param, param.size());
                kernel = &matern;
        } else if (which_kernel == "Square_Exponential") {
                std::cout << "Square Exponential kernel is used!" << std::endl;
                Kernel_SE se(param, param.size());
                kernel = &se;
        } else {
                std::cout << "Cannot identify the kernel" << std::endl;
                exit(1);
        }   
        input_dim = sample.dim;
        input_size = sample.size;
        L_chol.resize(sample.size, sample.size);
        Eigen::MatrixXd cov_matrix = Eigen::MatrixXd::Zero(sample.size, sample.size);
        get_cov_matrix(sample.X, input_size, sample.X, input_size, cov_matrix);
        get_chol(cov_matrix);
}

1 个答案:

答案 0 :(得分:1)

您正在存储超出范围的临时地址。在指向范围之外的地方使用*kernel是未定义的行为。

kernel的类型应为std::unique_ptr<X>,而不是X*类型。

替换为:

 kernel = std::make_unique<Kernel_Matern>(param, param.size());

或:

 kernel = std::make_unique<Kernel_SE>(param, param.size());

有问题的两行。

如果您有将kernel传递给函数的代码,则应传递kernel.get()

请注意,这是阻止复制GP实例,但不能移动它们,因为唯一的ptr只能移动。如果您有一个将值和指针都存储到其自己的值中的类型,则无论如何将其复制可能是一个错误。