Har*_*nak 3 c++ java undefined-behavior
我正在对C++进行一些模拟,我遇到了一个奇怪的问题.我有以下函数返回double的向量:
vector<double> processSimulation(int Q){
//do things
vector<double> output;
output.push_back(mean);
output.push_back(variance);
return output;
}
Run Code Online (Sandbox Code Playgroud)
总的来说,我有以下几点:
//define Q
vector<double>::iterator it = processSimulation(Q).begin();
double mean = *it;
double variance = *(it+1);
Run Code Online (Sandbox Code Playgroud)
问题是我得到了一个错误的数字(e-305)和方差的正确数字.我试图自己解释这种行为,我认为这可能是由未定义的行为引起的,因为迭代器指向函数中的旧向量,现在已超出范围并且不再存在.我对么? 可能我只是幸运,方差是正确的,因为它也可能是错的.
我将代码更改为
vector<double> output = processSimulation(Q);
vector<double>::iterator it = output.begin();
//same as before
Run Code Online (Sandbox Code Playgroud)
它工作得很好,所以这加强了我的创作.
此外,我注意到一个调试器很奇怪:当试图找出发生了什么(在修复代码之前)时,我通过调试查看了均值和方差的值,它们都是错误的.虽然,当我运行程序时,只有平均值是错误的(我已经尝试了很多次并且它总是:在调试时都错了,在运行时意味着错误和方差正确).这里发生了什么?
Java问题:嗯,我遇到的这个问题真的很烦我,因为经常在Java中,为了缩短事情,我没有定义新对象,而是直接在返回该对象的函数上使用方法(如本例所示) .虽然,我从来没有遇到任何问题.我是否一直在做无意识的事情(幸运的是)?或者只是在Java中没有这样的行为存在,因为应该返回对象的函数实际上返回指向它们的指针而真正的对象总是在堆中(并且在没有引用它们时被包围)?
希望你能澄清我的疑惑!
这是人们在关于在rvalues上链接调用而不是将结果存储在局部变量中时所犯的一个非常常见的错误.
vector<double>::iterator it = processSimulation(Q).begin();
Run Code Online (Sandbox Code Playgroud)
在上面,你的processSimulation(Q)电话会回来vector<double>.然后,您将获得一个迭代器到vector的开头并存储它.既然结果向量不再在范围内,它就会被销毁.这留下了一个悬垂的迭代器.
现在你开始使用它.请记住,迭代器包含有效信息,但它指向不再存在的对象:
double mean = *it; // undefined behaviour
double variance = *(it+1); // undefined behaviour
Run Code Online (Sandbox Code Playgroud)
把它想象成有点像这样:
vector<double>::iterator it;
{
vector<double> result = processSimulation(Q);
it = result.begin();
}
double mean = *it; // boom
Run Code Online (Sandbox Code Playgroud)
当您更改代码以将返回值存储在局部变量中时,将定义行为,前提是向量在您使用迭代器的整个时间内保持在范围内.
所以这是正确的(除了你问题上与C++风格相关的评论):
vector<double> output = processSimulation(Q);
vector<double>::iterator it = output.begin();
double mean = *it;
double variance = *(it+1);
Run Code Online (Sandbox Code Playgroud)
但是您可以轻松地抛弃迭代器并使用数组索引运算符:
double mean = output[0];
double variance = output[1];
Run Code Online (Sandbox Code Playgroud)
您可能需要考虑返回自己的封装此信息的结构,而不是向量.或者至少切换到使用std::pair<double, double>.