Unmanaged C++ object lifetime

B

Bob Altman

Hi all,

I have a basic question regarding holding references to objects in unmanaged
C++. Suppose my unmanaged C++ class has a method that accepts a reference
to an object as an argument, and stores the object reference in a stack
object, and another method that uses the stored objects in the stack object,
like this:

void MyClass::AcceptString(const string& myArg) {
m_myStack.push(myArg); // declared as stack<string> m_myStack
}

void MyClass::DoSomething() {
string& s = m_myStack.Top();
<Do something with s>
}

Now, suppose this method is called with code that looks like this:

MyClass t;
t.AcceptString("Some text");
t.DoSomething();

As I understand things, the compiler creates a temporary string object
containing "Some text" and passes it to my method. My question is, what is
the lifetime of that temporary string object? I assume that nothing in C++
does reference counting or anything like that to keep my private reference
"alive". Since my method has grabbed a reference to the string, I assume
that I'm at risk of trying to access it after the caller to my method has
deallocated it. Is this all correct? To be safe, do I need to store a copy
of the string in the stack object, even though 99.9% of the time the caller
will not destroy the string while I'm using it?
 
C

Carl Daniel [VC++ MVP]

Bob said:
Hi all,

I have a basic question regarding holding references to objects in
unmanaged C++. Suppose my unmanaged C++ class has a method that
accepts a reference to an object as an argument, and stores the
object reference in a stack object, and another method that uses the
stored objects in the stack object, like this:

void MyClass::AcceptString(const string& myArg) {
m_myStack.push(myArg); // declared as stack<string> m_myStack
}

void MyClass::DoSomething() {
string& s = m_myStack.Top();
<Do something with s>
}

Now, suppose this method is called with code that looks like this:

MyClass t;
t.AcceptString("Some text");
t.DoSomething();

As I understand things, the compiler creates a temporary string object
containing "Some text" and passes it to my method. My question is,
what is the lifetime of that temporary string object?

It survives up to the end of the complete statement in which it was created.
In this case, your AcceptString function made a copy of the temporary and
pushed that onto the stack, and the temporary is now gone.
I assume that
nothing in C++ does reference counting or anything like that to keep
my private reference "alive".
Correct.

Since my method has grabbed a
reference to the string, I assume that I'm at risk of trying to
access it after the caller to my method has deallocated it. Is this
all correct?

Your method took a reference, but then made a copy of the whole object, so
there's no way you can access the temporary beyond it's lifetime.
To be safe, do I need to store a copy of the string in
the stack object, even though 99.9% of the time the caller will not
destroy the string while I'm using it?

You already are storing a copy.

-cd
 
B

Bob Altman

Thanks a million for the quick answer. That raises the obvious question of
why a copy of my object is given to stack.push() rather than a reference to
it. Intellisense tells me that the function signature is:

void std::stack<string>::push(const std::stack<string>::value_type & _Val)

As I read this gibberish, it looks like my variable is being passed by
reference to the push() routine. I would have expected the string that was
given to my function by reference to be given to push() by reference, not by
value (which would create a copy of the string).
 
A

Arnaud Debaene

Bob said:
Thanks a million for the quick answer. That raises the obvious question
of why a copy of my object is given to stack.push() rather
than a reference to it. Intellisense tells me that the function
signature is:
void std::stack<string>::push(const std::stack<string>::value_type &
_Val)
As I read this gibberish, it looks like my variable is being passed by
reference to the push() routine. I would have expected the string
that was given to my function by reference to be given to push() by
reference, not by value (which would create a copy of the string).

All STL containers are value-based, which means they store copy of the
objects pushed on them. The push method take a reference to an opject and
make a copy of that object that is put on the stack.

Arnaud
MVP - VC
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top