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