Segfault when using Tree::merge_with
with default constructor
#283
-
Do I have to initialise either the root node or reserve the arena to clone a Tree from the default constructor // Much better THX!
ryml::substr loadFileToString(const std::string& path, ryml::Tree& tree)
{
std::ifstream ifs(path.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
std::ifstream::pos_type size = ifs.tellg();
ryml::substr bytes = tree.alloc_arena(size);
ifs.seekg(0, std::ios::beg);
ifs.read(bytes.data(), bytes.size());
std::cout << "Read bytes finished" << std::endl;
return bytes;
}
int main(int argc, char** argv)
{
ryml::Tree t;
ryml::NodeRef n = t.rootref();
auto substr = loadFileToString("block.yaml", t);
ryml::parse_in_place("block.yaml", substr, n);
// create clone
ryml::Tree clone;
// segfault
clone.merge_with(&t, 0, 0);
// ok
clone.reserve(substr.size());
clone.merge_with(&t, 0, 0);
// ok
auto n_clone = clone.rootref();
n_clone |= ryml::SEQ;
clone.merge_with(&t, 0, 0); Subquestion: I guess reserving the arena would speed up the |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
@captain-yoshi sorry, missed the update. This one is actually easy. Looking at the definition of void merge_with(Tree const* src, size_t src_node=NONE, size_t dst_root=NONE); It hints that you should use void Tree::merge_with(Tree const *src, size_t src_node, size_t dst_node)
{
_RYML_CB_ASSERT(m_callbacks, src != nullptr);
if(src_node == NONE)
src_node = src->root_id();
if(dst_node == NONE)
dst_node = root_id(); // <- here. this will mutate and get you a valid root_id
_RYML_CB_ASSERT(m_callbacks, src->has_val(src_node) || src->is_seq(src_node) || src->is_map(src_node));
// ...
} There is a nagging chicken-and-egg problem with having a root node. The current situation has it so that calling So other than the call to clone.merge_with(&t); // the standard way
clone.merge_with(&t, t.root_id(), clone.root_id()); // calling root_id() will mutate clone and call reserve() What you should not do is call with |
Beta Was this translation helpful? Give feedback.
@captain-yoshi sorry, missed the update. This one is actually easy. Looking at the definition of
.merge_with()
:It hints that you should use
NONE
to merge at the root. That also contemplates your situation, specifically about the prior inexistence of root in a default-constructed tree. Looking at the preamble of the function: