'Why does std::pair return such a random 'second' value?

The issue is that I want to return a pair containing my key and value {8, 8} for example. Instead I get a rather random pair back {8, 19259321} for example, and I'm not sure why, but I'm guessing I'm trying to do something with references that is causing UB. Below is a reproducible example:

#include <iostream>

template <typename Key, typename Value>
class Tree {
public:
    class Node {
    public:
        Key key;
        Value value;

        Node(Key k, Value v)
        {
            key = k;
            value = v;
        }
    };

    class iterator {
        using pointer_type = Node*;
        using reference = std::pair<const Key, Value>&;

        pointer_type t_Ptr;
    public:
        iterator(pointer_type ptr) : t_Ptr(ptr) {}

        // For the sake of the minimal reproduciable problem, this is the only operator.
        reference operator*() const
        {
            return (std::pair<const Key, Value>&)(t_Ptr->key, t_Ptr->value);
        }
    };
private:
    size_t treeSize;
    Node* root;
};

int main()
{
    Tree<int, int>::Node* testNode = new Tree<int, int>::Node(8, 8);

    Tree<int, int>::iterator it = Tree<int, int>::iterator(testNode);
    std::pair<int, int> myPair = *it;
    std::cout << myPair.first << ", " << myPair.second << std::endl;
}

The issue is my dereference operator in the iterator.

I should also mention, that the reason my return statement below looks the way it does, is because it was the only solution I found, where I didn't get any errors. In all the other ways I tried returning a pair, it would give me an error similar to

couldn't convert from the list initializer to pair<const Key, Value>&

return (std::pair<const Key, Value>&)(t_Ptr->key, t_Ptr->value);


Solution 1:[1]

I solved the issue. There was a shadowing issue firstly, which I believe I fixed. And instead of having two variables in my class node 'Key' and 'Value', I made one std::pair variable instead, containig both key and value. Then I could return that pair, instead of trying to create and return a new temporary pair, that would cause UB. Fixed code below.

#include <iostream>

template <typename Key, typename Value>
class Tree {
public:
    // I removed the template here, as it was unnecessary.
    class Node {
    public:
        // Changed the two variables to a pair.
        std::pair<const Key, Value> pair;
        // Therefore constructor had to be changed too
        Node(Key k, Value v) : pair(k, v) {}
    };

    class iterator {
        using pointer_type = Node*;
        using reference = std::pair<const Key, Value>&;

        pointer_type t_Ptr;
    public:
        iterator(pointer_type ptr) : t_Ptr(ptr) {}

        // For the sake of the minimal reproduciable problem, this is the only operator.
        reference operator*()
        {
            // I could now just return the variable 'pair'
            return t_Ptr->pair;
        }
    };
private:
    size_t treeSize;
    Node* root;
};

int main()
{
    Tree<int, int>::Node* testNode = new Tree<int, int>::Node(8, 8);

    Tree<int, int>::iterator it = Tree<int, int>::iterator(testNode);
    std::pair<int, int> myPair = *it;
    std::cout << myPair.first << ", " << myPair.second << std::endl;

    return 0;
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1