# How to Perform Deep Copies of YAML Nodes in yaml-cpp

> Learn how to deep copy YAML nodes in yaml-cpp using YAML::Clone. Avoid shallow copies that share memory for robust data handling in your projects.

- Repository: [Jesse Beder/yaml-cpp](https://github.com/jbeder/yaml-cpp)
- Tags: how-to-guide
- Published: 2026-07-11

---

**Use `YAML::Clone(node)` to create a deep copy of a YAML node in yaml-cpp, as the default copy constructor and assignment operator only perform shallow copies that share underlying memory.**

In the **jbeder/yaml-cpp** library, `YAML::Node` objects manage their underlying data through a shared-memory holder. While this design makes shallow copies efficient, performing deep copies of YAML nodes in yaml-cpp requires explicit use of the `YAML::Clone` function rather than the standard copy constructor.

## Understanding Shallow vs Deep Copy Semantics

The `YAML::Node` class defined in [`include/yaml-cpp/node/node.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/node/node.h) provides a copy constructor (`Node(const Node& rhs)`) and assignment operator that perform shallow copies. These operations copy the smart pointer to the internal node data, meaning both the original and the copy reference the same memory.

When you modify a shallow copy, you simultaneously modify the original node because they share the same underlying `node_data` structure. This behavior is efficient for passing nodes around but problematic when you need independent copies.

## How to Deep Copy a YAML Node Using YAML::Clone

To create an independent deep copy, use the `YAML::Clone` function declared in [`include/yaml-cpp/node/node.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/node/node.h) and implemented in [`src/node.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/node.cpp). This function constructs a completely new node tree by emitting the source node's events into a fresh `NodeBuilder`.

The implementation in [`src/node.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/node.cpp) follows this pattern:

```cpp
Node Clone(const Node& node) {
    NodeEvents events(node);
    NodeBuilder builder;
    events.Emit(builder);
    return builder.Root();
}

```

Here, `NodeEvents` (from [`src/nodeevents.h`](https://github.com/jbeder/yaml-cpp/blob/main/src/nodeevents.h)) captures the source node's structure and values, while `NodeBuilder` (from [`src/nodebuilder.h`](https://github.com/jbeder/yaml-cpp/blob/main/src/nodebuilder.h)) constructs a new node hierarchy with its own memory allocation.

### The Clone Implementation Details

The deep copy process works by:
1. Creating a `NodeEvents` object that traverses the source node and records its structure
2. Instantiating a `NodeBuilder` to construct a fresh node tree
3. Emitting the recorded events into the builder, which reconstructs the entire hierarchy
4. Returning the root node from the builder, which now owns its own memory allocation

This process ensures that scalars, sequences, and maps are all duplicated with independent storage.

## Practical Code Examples

The following example demonstrates the difference between shallow and deep copying:

```cpp
#include <yaml-cpp/yaml.h>
#include <iostream>

int main() {
    // Load a YAML document with nested structure
    YAML::Node original = YAML::Load(R"(
        user:
          name: Alice
          age: 30
          hobbies:
            - reading
            - hiking
    )");

    // Shallow copy: shares underlying memory
    YAML::Node shallow = original;
    shallow["user"]["age"] = 31;  // Modifies original as well

    std::cout << "Original age: " << original["user"]["age"].as<int>() << "\n";  // Output: 31

    // Deep copy: independent memory using YAML::Clone
    YAML::Node deep = YAML::Clone(original);
    deep["user"]["age"] = 32;     // Does NOT affect original

    std::cout << "Original age after deep copy mod: " << original["user"]["age"].as<int>() << "\n";  // Output: 31
    std::cout << "Deep copy age: " << deep["user"]["age"].as<int>() << "\n";  // Output: 32
}

```

## When to Use Deep Copies vs Shallow Copies

Use **shallow copies** when you want to pass nodes by value without the overhead of duplicating data, or when multiple parts of your code need to view and modify the same underlying configuration.

Use **deep copies** via `YAML::Clone` when you need to:
- Modify a node without affecting the original template
- Branch processing logic where each branch needs independent state
- Preserve the original document while building a modified variant

## Summary

- The default `YAML::Node` copy constructor in [`include/yaml-cpp/node/node.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/node/node.h) performs a **shallow copy**, sharing memory with the source node.
- **Deep copies** require calling `YAML::Clone(node)`, which creates an independent node tree using `NodeEvents` and `NodeBuilder` as implemented in [`src/node.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/node.cpp).
- Shallow copies reflect modifications across all references, while deep copies produced by `Clone` are completely isolated.
- Use `YAML::Clone` whenever you need to mutate a node hierarchy without affecting the original document.

## Frequently Asked Questions

### Does yaml-cpp's copy constructor create a deep copy?

No, the copy constructor `Node(const Node& rhs)` defined in [`include/yaml-cpp/node/node.h`](https://github.com/jbeder/yaml-cpp/blob/main/include/yaml-cpp/node/node.h) creates a shallow copy that shares the underlying memory holder. Modifications to the copy will affect the original node. Use `YAML::Clone` for deep copying.

### What is the difference between YAML::Clone and the copy constructor?

The copy constructor performs a shallow copy by copying the shared pointer to internal data, while `YAML::Clone` creates a completely new node tree by replaying the source node's events through a `NodeBuilder`. As implemented in [`src/node.cpp`](https://github.com/jbeder/yaml-cpp/blob/main/src/node.cpp), `Clone` ensures the new node owns its own memory allocation.

### How does YAML::Clone handle complex nested nodes?

`YAML::Clone` recursively processes the entire node hierarchy using `NodeEvents` to emit events for all nested maps, sequences, and scalars, then reconstructs them via `NodeBuilder`. This creates a full deep copy of the entire tree structure, not just the top-level node.

### Is YAML::Clone efficient for large documents?

While `YAML::Clone` is more expensive than shallow copying due to the event emission and reconstruction process, it is the only way to achieve true data independence. For very large documents where performance is critical, consider using shallow copies with immutable access patterns or restructuring your logic to avoid deep copies when possible.