返回向量的第一个元素(重新)设置为 0
First element of returned vector is (re)set to 0
我在软件中使用给定的库时遇到了这个问题。一个函数返回我想要使用的const std::vector&
。但是,第一个值始终设置为零(或在我的原始代码中:所有坐标设置为 0.0 的 3D 矢量),尽管我事先存储的值不是。
类结构如下(示例代码如下):
-
ValueContainer
:包含值的std::vector< double >
和 gettervalues()
。 -
Object
:包含一个ValueContainer
和一个吸气valuesContainer()
。
在我的代码中,我使用以下方法检索值:
// First element always set to 0
const std::vector< double >& values = object.valuesContainer().values();
这导致了错误,即第一个元素设置为 0.0
。我可以通过复制值来规避问题:
// This works as expected
std::vector< double > values = object.valuesContainer().values();
仔细检查后,我注意到,valuesContainer()
没有返回参考文献,而是返回ValueContainer
的副本。发生的情况是(在我的理解中),我在valuesContainer()
创建的临时对象上调用values()
,从而获得对临时对象的引用。这当然不会很好地工作,我希望在我的向量中获得"垃圾"数据,或类似的东西。
但是:除了第一个值之外的所有值似乎都可以!现在,真正的问题是:为什么它会这样工作?如果它只是未定义的行为,为什么第一个值设置为 0 而其他值保持不变?我很乐意对这个问题有更多的了解。
下面是在 Linux 上使用 gcc 4.8.1 测试的示例代码:
#include <iostream>
#include <iomanip>
#include <vector>
class ValueContainer
{
public:
ValueContainer();
inline const std::vector< double >& values() const;
//private:
std::vector< double > some_values_;
};
class Object
{
public:
ValueContainer valueContainerCopy() const
{
return values_;
}
const ValueContainer& valueContainerConstRef() const
{
return values_;
}
//private:
ValueContainer values_;
};
ValueContainer::ValueContainer()
{
// Just some test data
some_values_.push_back(1.2);
some_values_.push_back(3.4);
some_values_.push_back(5.6);
some_values_.push_back(7.8);
some_values_.push_back(9.0);
}
const std::vector< double >& ValueContainer::values() const
{
return some_values_;
}
int main( int argc, char** argv )
{
Object obj;
const std::vector< double >& values_CopyRef = obj.valueContainerCopy().values();
const std::vector< double >& values_RefRef = obj.valueContainerConstRef().values();
std::vector< double > values_CopyCopy = obj.valueContainerCopy().values();
std::cout << "Pointers: " << std::endl
<< " - Original: " << &obj.values_.some_values_ << std::endl
<< " - CopyRef: " << &values_CopyRef << std::endl
<< " - RefRef: " << &values_RefRef << std::endl
<< " - CopyCopy: " << &values_CopyCopy << std::endl;
std::cout << "Data pointers: " << std::endl
<< " - Original: " << obj.values_.some_values_.data() << std::endl
<< " - CopyRef: " << values_CopyRef.data() << std::endl
<< " - RefRef: " << values_RefRef.data() << std::endl
<< " - CopyCopy: " << values_CopyCopy.data() << std::endl;
std::cout << "Data:" << std::endl;
for ( std::size_t i = 0; i < values_RefRef.size(); i++ )
{
std::cout << "i=" << i << ": " << std::fixed << std::setprecision(1)
<< "CopyRef: " << values_CopyRef[ i ] << ", "
<< "RefRef: " << values_RefRef[ i ] << ", "
<< "CopyCopy: " << values_CopyCopy[ i ]
<< std::endl;
}
return 0;
}
此示例的(重要)输出如下所示,您可以在其中看到,对临时对象的引用的第一个值设置为 0,其他值似乎没问题:
i=0: CopyRef: 0.0, RefRef: 1.2, CopyCopy: 1.2
i=1: CopyRef: 3.4, RefRef: 3.4, CopyCopy: 3.4
i=2: CopyRef: 5.6, RefRef: 5.6, CopyCopy: 5.6
i=3: CopyRef: 7.8, RefRef: 7.8, CopyCopy: 7.8
i=4: CopyRef: 9.0, RefRef: 9.0, CopyCopy: 9.0
const std::vector< double >& values_CopyRef = obj.valueContainerCopy().values();
这是存储对临时函数的引用,因为valueContainerCopy
函数被声明为
ValueContainer valueContainerCopy() const
{
return values_;
}
这会将向量values_
复制到返回的临时向量中。 然后,您将对该临时数据的引用存储,从而导致未定义的行为。
如果要将其存储为引用,则需要返回一个引用,这就是您在valueContainerConstRef
函数中所做的。
相关文章:
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++/Linux中设置单调时钟的一些技巧
- 如何将整数重新初始化/设置为空值
- 我想在我设置的几秒钟后重新启动我的程序
- Live555MediaServer 在每个新连接时重新启动流。为什么将"reuseSource"设置为 true 无法按预期工作?
- 重新设置小部件pyqt的布局
- STL 设置::查找重新定义的搜索
- 重新设置了以前的状态3查询
- 初始化过多的错误加上重新设置数组的函数
- 为什么可以重新设置参考参数
- 返回向量的第一个元素(重新)设置为 0
- GDB - 重新设置常量
- 使用 SetNamedSecurityInformation 重新设置GRANT_ACCESS
- 将数组的所有点设置为0对重新分配动态内存有不同的影响
- 如何重新缩放图像并将其设置为 QWidget
- 在QT 5中重新设置QT/QML映射
- 重新设置断点时出现GDB错误(无法访问内存)
- c++重新设置构造函数值
- 在我准备好分配它之前,将“unique_ptr”保留为未设置:这就是我重新分配它的方式吗?
- 重新设置istringstream对象