hi,
recently i discovered a memory leak in our code; after some investigation i
could reduce it to the following problem:
return objects of functions are handled as temporary objects, hence their
dtor is called immediately and not at the end of the function. to be able to
use return objects (to avoid copying) i often assign them to a const
reference.
now, casting a const return object from a function to a non-const reference
to this return object calls immediately the dtor of the return object
anyway, any further operation deals with a non-valid object then. if i do
this in two steps - first holding a const reference to the return object and
then const_casting it, everything works like i expected it.
does anybody know whether the compiler behaves correctly?
i use the following short example to illustrate my question:
const string getastring()
{
return string();
}
void funcWmemleak()
{
string& str = const_cast<string&>(getastring());
str = "test"; // this is already an invalid object because the dtor was
called before (and won't ever be called again of course)
}
void funcWOmemleak()
{
const string& str1 = getastring();
string& str = const_cast<string&>(str1);
str = "test";
}
int main()
{
funcWmemleak();
funcWOmemleak();
}
--
klaus triendl 5 3705
On Wed, 02 Jun 2004 08:09:01 GMT, "klaus triendl" <tr********@mbox.at>
wrote: hi,
recently i discovered a memory leak in our code;
I think you mean "use of a dangling reference" rather than "memory
leak".
after some investigation icould reduce it to the following problem: return objects of functions are handled as temporary objects, hence their dtor is called immediately and not at the end of the function. to be able to use return objects (to avoid copying) i often assign them to a const reference. now, casting a const return object from a function to a non-const reference to this return object calls immediately the dtor of the return object anyway, any further operation deals with a non-valid object then. if i do this in two steps - first holding a const reference to the return object and then const_casting it, everything works like i expected it.
does anybody know whether the compiler behaves correctly?
Yes, binding a temporary directly to a const reference extends the
lifetime of the temporary to match that of the reference. You can't
bind a temporary to a non-const reference, so there's no way of doing
the lifetime extension using a non-const ref.
Note, since you return a const string, using the returned string as a
non-const string results in undefined behaviour. You can only safely
use an object that has had const cast away as a non-const object if it
wasn't originally declared const.
Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"tom_usenet" <to********@hotmail.com> wrote in message
news:<a2********************************@4ax.com>. .. On Wed, 02 Jun 2004 08:09:01 GMT, "klaus triendl" <tr********@mbox.at> wrote:
hi,
recently i discovered a memory leak in our code; I think you mean "use of a dangling reference" rather than "memory leak".
in our code the returned object is a reference counting pointer and the
string "test" is a new object which is not freed causing a memory leak
(reported by the debugger as such).
after some investigation icould reduce it to the following problem: return objects of functions are handled as temporary objects, hence their dtor is called immediately and not at the end of the function. to be able
touse return objects (to avoid copying) i often assign them to a const reference. now, casting a const return object from a function to a non-const
referenceto this return object calls immediately the dtor of the return object anyway, any further operation deals with a non-valid object then. if i do this in two steps - first holding a const reference to the return object
andthen const_casting it, everything works like i expected it.
does anybody know whether the compiler behaves correctly? Yes, binding a temporary directly to a const reference extends the lifetime of the temporary to match that of the reference. You can't bind a temporary to a non-const reference, so there's no way of doing the lifetime extension using a non-const ref.
if the temporary is non-const i can bind it to a non-const reference. at
least with vc++7 it is possible.
Note, since you return a const string, using the returned string as a non-const string results in undefined behaviour. You can only safely use an object that has had const cast away as a non-const object if it wasn't originally declared const.
well, that's an argument; and i can easily solve that problem.
but my question still remains whether the const_cast in the function
"funcWmemleak" is a good reason that the non-const reference is a non-valid
object after the assignment or not.
--
klaus triendl
On Wed, 02 Jun 2004 14:07:20 GMT, "klaus triendl" <tr********@mbox.at>
wrote: Yes, binding a temporary directly to a const reference extends the lifetime of the temporary to match that of the reference. You can't bind a temporary to a non-const reference, so there's no way of doing the lifetime extension using a non-const ref.if the temporary is non-const i can bind it to a non-const reference. at least with vc++7 it is possible.
This is a non-conforming compiler extension. On VC7.1 I get a warning,
and compiling with /Za (ISO mode) I get an error. Note, since you return a const string, using the returned string as a non-const string results in undefined behaviour. You can only safely use an object that has had const cast away as a non-const object if it wasn't originally declared const.well, that's an argument; and i can easily solve that problem.
Indeed, that paragraph was just an aside.
but my question still remains whether the const_cast in the function "funcWmemleak" is a good reason that the non-const reference is a non-valid object after the assignment or not.
If you perform the const_cast, then you are not directly binding the
reference to the temporary, and the lifetime will not be extended,
hence you have a "dangling reference" that you can't use. It is
synonymous to this conforming code that exhibits the same problem, and
doesn't use any Microsoft extensions:
#include <string>
#include <iostream>
using namespace std;
int main()
{
string const& s = static_cast<string const&>(string("foo"));
cout << s << '\n';
}
Because s isn't bound directly to the temporary (it is bound to the
result of the static cast), it doesn't extend the temporary's lifetime
and the cout call has undefined behaviour since the temporary has
already been destroyed. Remove the static_cast and it's fine. See
12.2/5 in the C++ standard.
Clear?
Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"klaus triendl" <tr********@mbox.at> wrote in message news:<sa******************@news.chello.at>... after some investigation icould reduce it to the following problem: return objects of functions are handled as temporary objects, hence their dtor is called immediately and not at the end of the function. to be able touse return objects (to avoid copying) i often assign them to a const reference. now, casting a const return object from a function to a non-const referenceto this return object calls immediately the dtor of the return object anyway, any further operation deals with a non-valid object then. if i do this in two steps - first holding a const reference to the return object andthen const_casting it, everything works like i expected it.
does anybody know whether the compiler behaves correctly?
Yes, binding a temporary directly to a const reference extends the lifetime of the temporary to match that of the reference. You can't bind a temporary to a non-const reference, so there's no way of doing the lifetime extension using a non-const ref. if the temporary is non-const i can bind it to a non-const reference. at least with vc++7 it is possible.
Note, since you return a const string, using the returned string as a non-const string results in undefined behaviour. You can only safely use an object that has had const cast away as a non-const object if it wasn't originally declared const. well, that's an argument; and i can easily solve that problem. but my question still remains whether the const_cast in the function "funcWmemleak" is a good reason that the non-const reference is a non-valid object after the assignment or not.
Yes, it is a valid reference until the const reference that the
temporary was originally bound to is destroyed (i.e. goes out of
scope), provided that the destructor for the original object is not
called in the interim (which is highly unlikely given the context).
HTH, Dave Moore
> Because s isn't bound directly to the temporary (it is bound to the result of the static cast), it doesn't extend the temporary's lifetime and the cout call has undefined behaviour since the temporary has already been destroyed. Remove the static_cast and it's fine. See 12.2/5 in the C++ standard.
Clear?
clear as glass :)
thx for the explanation. it's good to know that the compiler considers the
const_cast a function returning a result.
and thx to dave moore for your posting.
klaus This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Christopher Benson-Manica |
last post by:
If you had an unsigned int that needed to be cast to a const myClass*,
would you use
const myClass* a=reinterpret_cast<const myClass*>(my_val);
or
const myClass* a=(const myClass*)myVal;
...
|
by: MSG |
last post by:
The answer is neither. Use macros.
#define ALLOC(size, type) ((type) *) malloc((size) * sizeof(type))
#define NEW(type, name, size) (type) * (name) = ALLOC((size), (type))
They are both ...
|
by: Martin |
last post by:
Two questions relating to FAQ answer 12.42.
(1) In the statement
s.i16 |= (unsigned)(getc(fp) << 8);
i16 is declared int. The reason for casting to (unsigned) is explained as
guarding...
|
by: google-newsgroups |
last post by:
Hello,
even (or because?) reading the standard (ISO/IEC 9899/1999) I do not
understand some issues with volatile. The background is embedded
programming where data is exchanged between main...
|
by: Daniel |
last post by:
HI,
<asp:TableCell BackColor="#000066" ID="tblcell" Width='<%#
DataBinder.Eval(Container.DataItem, "PRODUCT_ID") %>'/>
code at the above is displaying the message Specified cast is not valid....
|
by: the.duckman |
last post by:
G'Day.
Anybodey got an idea on this problem.
Say I have a function object doCast(object obj, Type t);
It's job is to cast the obect (obj) to a new type (t) and return it.
Sounds so...
|
by: Joe |
last post by:
I need to cast the correct way
HMENU mymenu;
int stuff;
....
stuff=(int)(long)(HMENU)mymenu;
....
|
by: Pavel Minaev |
last post by:
There was an earlier discussion regarding which one is faster - a
throwing cast - "(Foo)obj", or a non-throwing one - "obj as Foo", when
both are available for a given type and value. The consensus...
|
by: Lloyd Dupont |
last post by:
Don't mistake generic type for what you would like them to be!!
IFoo<Ahas nothing in common with IFoo<B>!
They are completely different type create dynamically at runtime.
What you ask is a...
|
by: ryjfgjl |
last post by:
ExcelToDatabase: batch import excel into database automatically...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM).
In this month's session, we are pleased to welcome back...
|
by: jfyes |
last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
|
by: PapaRatzi |
last post by:
Hello,
I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
|
by: Defcon1945 |
last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
|
by: Shællîpôpï 09 |
last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome former...
| |