Question

If I assign a new variable to an old variable, the old variable is no longer addressable, however I'm not sure when it goes out of scope:

for example:

std::vector<int> foo() {
    return std::vector<int>{3,4,5};
}

int main() {

    std::vector<int> v{1,2,3};

    v = foo();  //when is the first vectors destructor called? 
                //before or after "foo()" has been called?
                //is it called?

}

And, if it isn't called till after foo has been called, how do I destroy v before I call foo()?

Was it helpful?

Solution

v = foo();

The above statement is a move assignment (copy assignment for pre-C++11 compilers). In either case, the result of the call to foo() is required for the assignment, since it is the input argument to the respective assignment operator, so the freeing of resources managed by v is done after the call to foo(), and the memory management is performed within the copy/move assignment operator.

Notice I didn't mention any calls to the destructor of v, because the destructor will not be called at that point. The memory that is being managed by v will be deallocated, with the destructors for the individual elements being invoked. In case of a vector<int>, the destructor of each int is a NOP, so they're only conceptually invoked.

The vector will then allocate enough memory to be able to hold the contents of the vector returned by foo (copy assignment), or take control of the memory being managed by the vector returned by foo (move assignment). Of course, the vector implementation is free to skip the deallocation followed by allocation if the existing memory is large enough to hold the new contents.

The destructor for v will run when v goes out of scope. In the example you've provided, this happens at the end of main().

OTHER TIPS

The return value of foo() is created prior to assigning it to v in main().

The destructor is called when it goes out of scope, that is at the end of main.

The sequence is that you call foo(), which returns a vector. Then a copy assignment operator is called, which copies the returned vector to the original one. Afterwards the returned vector is destroyed, as it is a temporary variable.

v will only be destructed when it goes out of scope.

However, foo() creates a temporary object, which is then returned, which is then assigned to v. The temporary is then destroyed (after it has been assigned to v). v is then destroyed at the end of main().

Note that in practice, the compiler optimizes a lot of this -- it does return value optimization, so that instead of returning a temporary which is then assigned to v, it works directly on v. Also, there's a move assignment operator which swaps the ownership of the memory from the temporary into v without doing a copy of it first.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top