Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the expression `new T` evaluate to an rvalue or an lvalue?

I am currently reading this tutorial/explanation of rvalue references:

http://thbecker.net/articles/rvalue_references/section_07.html

In the 2nd to last paragraph, the author mentions that "the argument of the copy constructor of T in the body of factory is an lvalue". The code he is referring to is this:

template<typename T, typename Arg> 
shared_ptr<T> factory(Arg const & arg)
{ 
  return shared_ptr<T>(new T(arg));
}

I realise that new T(arg) constructs a T object on the heap, but isn't the returned value a temporary pointer value which will be lost if not used (leading to a memory leak I guess), and hence an rvalue?

EDIT: Just to clarify, I understand that there will be no memory leak in this example. I just meant that, if the pointer value would have not been used we would have no way of accessing the constructed T object and hence we'd get a memory leak.

like image 851
elatalhm Avatar asked Sep 25 '14 17:09

elatalhm


People also ask

What is the difference between an lvalue and an rvalue?

An lvalue refers to an object that persists beyond a single expression. An rvalue is a temporary value that does not persist beyond the expression that uses it.

Is an rvalue reference an lvalue?

An lvalue is an expression that yields an object reference, such as a variable name, an array subscript reference, a dereferenced pointer, or a function call that returns a reference. An lvalue always has a defined region of storage, so you can take its address. An rvalue is an expression that is not an lvalue.

Can you pass an lvalue to an rvalue reference?

By overloading a function to take a const lvalue reference or an rvalue reference, you can write code that distinguishes between non-modifiable objects (lvalues) and modifiable temporary values (rvalues). You can pass an object to a function that takes an rvalue reference unless the object is marked as const .

What is an lvalue expression?

Lvalue expression is any expression with object type other than the type void , which potentially designates an object (the behavior is undefined if an lvalue does not actually designate an object when it is evaluated). In other words, lvalue expression evaluates to the object identity.


1 Answers

Short answer, I'm sure someone will write a longer one, but:

new gives you a pointer rvalue: new int = nullptr; fails to compile with error about requiring an lvalue.

Dereferencing that pointer gives you an lvalue: *(new int) = 5; will compile (this naive statement also leaks memory because pointer is lost, of course).

The copy constructor takes a reference, so if you have pointer to object, you need to dereference it.

If you lose the pointer, then you can't delete it, so it won't get destructed and the heap memory will not get freed (until the program exits and memory is returned to the OS).

If you put the pointer to some other object which can take ownership of it, like a shared_ptr, then you do not lose the pointer. The other object will delete it according to its semantics, at the latest when the other object (or the last one, in a case of shared ownership, like with shared_ptr) itself gets destructed.

like image 91
hyde Avatar answered Oct 09 '22 01:10

hyde