我创建了一个 C++ 模板化“样本”函数,它使用 Boost 随机数生成器从任何提供多项式分布的对象中采样作为可迭代对象。
/** Sample a value from a multinomial law with coefficient of modalities provided */
template<typename T>
int sample(const T& proportion)
{
boost::random::uniform_real_distribution<> uni(0.,
1.);
boost::variate_generator<boost::random::mt19937&,
boost::random::uniform_real_distribution<> > generator(rng_,
uni);
Real x = generator();
Real cumProb = 0.; // cumulative probability
int index = 0;
for(typename T::const_iterator it = proportion.begin();
it != proportion.end();
++it)
{
cumProb += *it;
if (x < cumProb)
{
return index;
}
++index;
}
return -1; // to accelerate sampling, no check have been computed on modalities to verify that is it actually a probability distribution
};
例如,当我使用特征向量调用它时(我在其上添加了一个迭代器),我在 Valgrind 中收到以下错误:
==4917== Conditional jump or move depends on uninitialised value(s)
==4917== at 0xD7B0A3C: int mixt::MultinomialStatistic::sample<Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, -1, -1, false> >(Eigen::Block<Eigen::Matrix<double, -1, -1, 0, -1, -1> const, -1, -1, false> const&) (mixt_MultinomialStatistic.h:76)
==4917== by 0xD7B0538: mixt::ClassSampler::sampleIndividual(int) (mixt_ClassSampler.cpp:63)
==4917== by 0xD7ADBE6: mixt::IMixtureComposerBase::sStep(int) (mixt_IMixtureComposerBase.cpp:94)
==4917== by 0xD7ADAF0: mixt::IMixtureComposerBase::sStep() (mixt_IMixtureComposerBase.cpp:68)
==4917== by 0xD7AC3DE: mixt::SemStrategy::run() (mixt_SEMStrategy.cpp:83)
==4917== by 0xD74F742: mixtCompCluster(Rcpp::Vector<19, Rcpp::PreserveStorage>, Rcpp::Vector<19, Rcpp::PreserveStorage>, int, double) (mixtCompCluster.cpp:123)
==4917== by 0xD749A61: RMixtComp_mixtCompCluster (RcppExports.cpp:18)
==4917== by 0x4F0ADE7: ??? (in /usr/lib/R/lib/libR.so)
==4917== by 0x4F4981A: Rf_eval (in /usr/lib/R/lib/libR.so)
==4917== by 0x4F4B92F: ??? (in /usr/lib/R/lib/libR.so)
==4917== by 0x4F49622: Rf_eval (in /usr/lib/R/lib/libR.so)
==4917== by 0x4F4A93E: Rf_applyClosure (in /usr/lib/R/lib/libR.so)
==4917==
行 mixt_MultinomialStatistic.h:76 对应于 if (x < cumProb)
.在我看来,此时 x 和 cumProb 都已定义。我该如何调试它?
编辑
根据 Beta 在评论中的建议,我添加了以下虚拟代码:
if (x < 1000.)
{}
if (-1000. < cumProb)
{}
if (x < cumProb)
{ ...
我仍然收到关于 if (x < cumProb)
行的错误报告.
使用 --track-origins=yes
选项启动 valgrind 时,我得到以下指示
==10074== Uninitialised value was created by a stack allocation
指向指令:
cumProb += *it;
最佳答案
在我的(单元测试)代码中搜索未初始化的值时,我遇到了一个有点类似的问题,发现特征矩阵(和 vector )的值没有在它们的默认构造函数中初始化。我在一个结构中有这样一个 vector ,最终使用如下语句解决了这个问题:
struct MyStruct {
Eigen::Vector2f myVector;
};
MyStruct myStruct{}; // Does not initialize myVector's values!
std::cout << "myVec = " << myStruct.myVector << std::endl; // Causes valgrind to warn about uninitialized variables
myStruct.myVector = Eigen::Vector2f(0.0f, 0.0f);
std::cout << "myVecInit = " << myStruct.myVector << std::endl; // No valgrind warning
请注意,我很难对此进行调试,因为当使用 gdb 启动单元测试时, vector 虽然未初始化但恰好包含零。
关于c++ - Valgrind 错误,未初始化的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30866458/