简体   繁体   中英

C++ return vector.at() address changes

Why does the address of the element ping-pong?

I have something like this:

std::vector<double> foo(...);

int main(){
    std::vector<double> x;
    x.assign(1,0.0);
    x = foo(...);
    print &x.at(0); // 0x607210

    x = foo(...);
    print &x.at(0); // 0x607240

    x = foo(...);
    print &x.at(0); // 0x607210
}

Why does the address of the element ping-pong? The base address of x remains the same, and the value x.at(0) is always correct. There's a subtlety here that I do not understand.

The foo function returns a new vector. Since the result is an r-value, it will be move-assigned to x . Since each new vector had their distinct buffers, so too will the buffers of x be distinct after each move assignment.

A buffer cannot share its address with another existing buffer, and both the returned r-value and x have overlapping lifetimes, so the buffer address has to change. But a distinct buffer can have an address of a previously destroyed buffer which is why the repetition that you observed is possible.

x=foo() is assigning a std::vector<double> to x . According to this documentation , operator= always invalidates pointers, references and iterators to it's elements. It's expected that the address of the elements will change. That these addresses "ping-pong" is just the behavior you happened to observe. It's not something that can be relied on.

Consider what assigning to a std::vector means in this case. The move assignment operator will replace the underlying data of x with the underlying data of the std::vector being returned by foo() . The new array couldn't have had the same address as the one that it's replacing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM