c++pointersconstructorstdvectorc++98

Stop overwriting addresses in vector?


My problem is along the following lines. I have a vector class elementList which contains elements describing triangles along a surface, but when I add individually constructed elements into elementList via emplace_back, their address changes.

If you need more code let me know, but I removed the fluff to get what I think are the essentials. First elementList:

class elementList
{
public:
    elementList(std::string filename);

    std::vector<element> const& get_elements() const;

private:
    std::vector<element> m_elements;
};

and I parse information from a source txt file into it. The element class, excluding some unnecessary bits, looks like this

class element
{
public:

    element(float x11, float x12, float x21, float x22, float x31, float x32); 

    std::vector<Node> const& nodes() const;
    std::vector<Edge> const& edges() const;
        [...]
    
private:

    std::vector<Node> m_nodes;
    std::vector<Edge> m_edges;
    [...]
};

So I parse a source file while constructing elementList

elementList::elementList(std::string filename)
{
        [...] //parse node coordinates from source file

        m_elements.emplace_back(element(x11,x12,x21,x22,x31,x32)); //1
}

The construction works, but what surprises me is that the address of top level variables in the element changes. If e.g. within the element constructor I print out

element::element(float x11, float x12, float x21, float x22, float x31, float x32)
{
        [...]
        std::cout << &m_nodes[0] << std::endl;
}

I get a different address than when I am in the elementList constructor and print out

elementList::elementList(std::string filename)
{
        [...]
        m_elements.emplace_back(element(x11,x12,x21,x22,x31,x32)); //1
        Node initialNode = m_elements.at(0).nodes().at(0);
        std::cout << &initialNode;
}

This consistently happens with all elements, only the addresses change, none of the node values. Is there a way to append an element to elementList and maintain the same memory address? Otherwise this would throw off some connectivity information I store within each individual element.

My guess is at step //1 the code actually copies the element instead of inserting it as is, is there a way to avoid that?


Solution

  • In your code elementList::elementList:

    Node initialNode = m_elements.at(0).nodes().at(0);
    

    Notice that initialNode is a local variable, and its value is copy-initialized from m_elements.at(0).nodes().at(0). That is, only the "value" in Node object is copied into initialNode.

    So when you take the address (&initialNode), the value returned is the address of local variable initialNode, not the address of the object in std::vector<Node>. To take the address, use &m_elements.at(0).nodes().at(0) instead.