У меня была эта проблема при использовании данной библиотеки в моем программном обеспечении. Функция возвращает const std::vector&
, которую я хочу использовать. Однако первое значение всегда устанавливается равным нулю (или в моем исходном коде: 3D-вектор со всеми координатами, установленными в 0.0), хотя значение, которое я сохранил в нем заранее, не было.Первый элемент возвращаемого вектора (re) установлен в 0
Класс структуры состоит в следующем (пример кода ниже):
ValueContainer
: содержитstd::vector<double>
значений и геттерvalues()
.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
. Что происходит (в моем понимании), я вызываю values()
на временном объекте, созданном valuesContainer()
и, таким образом, получаю ссылку на временный объект. Это, конечно, не сработает, и я ожидаю получить данные «мусора» в моем векторе или что-то в этом роде.
Однако: все значения, кроме первого, кажутся вам в порядке! Теперь, реальный вопрос: почему он работает так? Если это просто неопределенное поведение, почему первое значение установлено равным 0, а остальные остаются неизменными? Я был бы рад получить немного больше информации по этому вопросу.
Вот теперь следует пример кода, тестирование с помощью GCC 4.8.1 на Linux:
#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
Я знал это, но все же спасибо за ответ. Но мне все же хотелось бы знать, почему именно в первой позиции в векторе (или в позиции памяти, где раньше использовался первый элемент временного вектора). И хотя «неопределенное поведение» может быть ответом, это на самом деле не удовлетворяет мое любопытство;) Может ли это иметь что-то. делать с уничтожением вектора темрира? – Hanno
Простой ответ - неопределенное поведение не определено. Как пару других участников сказали бы: он может заказать вам пиццу ... поскольку она не определена, все, что происходит, будет «правильным» для этой системы. –