jbeder / yaml-cpp

A YAML parser and emitter in C++
MIT License
4.91k stars 1.78k forks source link

YAML::Nodes alias rather than moving when using std::vector::erase, std::iter_swap and similar methods. #1209

Open rr-mark opened 11 months ago

rr-mark commented 11 months ago

The following unit test fails

#include "gtest/gtest.h"
#include <yaml-cpp/yaml.h>
#include <vector>

TEST(VectorErase, ProducesVectorContainingCorrectElements) {
    YAML::Node a;
    a["name"] = "a";
    YAML::Node b;
    b["name"] = "b";
    YAML::Node c;
    c["name"] = "c";
    std::vector<YAML::Node> vec{a, b, c};
    vec.erase(vec.begin());
    EXPECT_EQ(vec[0]["name"].as<std::string>(), "b");
}

When vec.erase(vec.begin()) is called, instead of vec containing names {"b", "c"}, it instead contains names {"c", "c"}.

My guess is that this is something to do with aliasing rather than copying when the vector elements are moved. This is likely an issue with the move constructor or move assignment of the Node.

I am using libcpp-yaml0.6, as I am currently limited to Ubuntu 20.04.

rr-mark commented 11 months ago

Some other std::vector operations fail in the same way, including

std::iter_swap(vec.begin(), vec.begin()+1);
rr-mark commented 10 months ago

This is likely a duplicate of https://github.com/jbeder/yaml-cpp/issues/721, and that issue is probably easier to test with.

rr-mark commented 10 months ago

I think this issue will be resolved by https://github.com/jbeder/yaml-cpp/pull/810