Motivation for smart pointers

  • Thread starter christopher diggins
  • Start date
C

christopher diggins

What I am trying to answer is, what the most prominent motivation for
implenting and using smart pointers in C++ is. Is it primarily to reduce
bugs resulting from memory access errors or primarily to permit lazy
deallocation designs (i.e. designs that rely on non-determined non-fixed
non-explicit deallocation of memory)? Obviously both are advantages, but I
want to know if programmers are finding that lazy deallocation is one of the
major uses of smart pointers.

For some the motivation behind this question may be interesting. The
motivating question is : do C++ programmers / software designers perceive
any advantages to explicitly deallocating memory over implicitly
deallocating memory when the last reference is used?
 
L

lilburne

christopher said:
What I am trying to answer is, what the most prominent motivation for
implenting and using smart pointers in C++ is. Is it primarily to reduce
bugs resulting from memory access errors or primarily to permit lazy
deallocation designs (i.e. designs that rely on non-determined non-fixed
non-explicit deallocation of memory)? Obviously both are advantages, but I
want to know if programmers are finding that lazy deallocation is one of the
major uses of smart pointers.

For some the motivation behind this question may be interesting. The
motivating question is : do C++ programmers / software designers perceive
any advantages to explicitly deallocating memory over implicitly
deallocating memory when the last reference is used?

How does the last reference to a reference counted pointer
becoming unused, differ from explicitely deleting a pointer
when it is no longer used?
 
D

Daniel T.

christopher diggins said:
What I am trying to answer is, what the most prominent motivation for
implenting and using smart pointers in C++ is. Is it primarily to reduce
bugs resulting from memory access errors or primarily to permit lazy
deallocation designs (i.e. designs that rely on non-determined non-fixed
non-explicit deallocation of memory)? Obviously both are advantages, but I
want to know if programmers are finding that lazy deallocation is one of the
major uses of smart pointers.

First, I think the use of smart pointers does not fall under the
category of "designs that rely on non-determined, non-fixed,
non-explicit deallocation of memory." The deallocation is still highly
determined, very fixes, and explict in my view. Contrast this with, for
example, a garbage collector running in another thread. In this case,
the deallocation cannot be determined by looking at the code. Not so
with a smart pointer.

I think the primary reason for using smart pointers is to reduce bugs in
a design.
 
G

Gianni Mariani

christopher said:
What I am trying to answer is, what the most prominent motivation for
implenting and using smart pointers in C++ is. Is it primarily to reduce
bugs resulting from memory access errors or primarily to permit lazy
deallocation designs (i.e. designs that rely on non-determined non-fixed
non-explicit deallocation of memory)? Obviously both are advantages, but I
want to know if programmers are finding that lazy deallocation is one of the
major uses of smart pointers.

Ever tried to write a complex algorithm with reference counted objects ?

Exception safety is the other one. In theory, if you're a real stud,
you can probably get it right, but it's not exactly maintainable and
when someone comes along and throws an exception - all hell breaks loose.

smart pointers do not necessarilt have to work for reference counted
pointers - see std::auto_ptr.
For some the motivation behind this question may be interesting. The
motivating question is : do C++ programmers / software designers perceive
any advantages to explicitly deallocating memory over implicitly
deallocating memory when the last reference is used?

I suspect you can use smart ptrs explicitly to delete object when they
are no longer used - so I don't know where you "implicity" really comes
from.

e.g.

{
gianni_ptr<typ *> x = new typ;


x->stuff();

} <<<--- x's destructor does magic here


I think you might be thinking like in C where the code you need to
actually put in your own destructor call. C++ provides more semantics
than that - the compiler will insert that destructor call for x
whereever it's needed.

The RAII (Resource Aquisition Is Initialization) idiom is used here but
it's used in more than just this - it's also used for mutexes for
example. It's probably one of the cornerstones of the language because
if you use it correctly - it's really easy to write maintainable code.
 
H

Howard Hinnant

Gianni Mariani said:
The RAII (Resource Aquisition Is Initialization) idiom is used here but
it's used in more than just this - it's also used for mutexes for
example. It's probably one of the cornerstones of the language because
if you use it correctly - it's really easy to write maintainable code.

Amen! Smart pointers are not about reference counting. They're about
destructing/deleting properly -- implicitly!

void foo()
{
Sptr<T> ptr(new T);
if (condition 1)
return;
while (condtion 2)
do_something_that_might_throw();
if (condition 3)
throw "error";
*ptr = T();
set_state_with_ptr_might_throw(ptr);
}

Trying to write code like the above without the help of proper
destruct/delete semantics is much harder without smart pointers or
without destructors.

Ever seen clean-up handlers pushed/popped from a "stack" in C? (e.g.
pthread_cleanup_push/pop) Destructors are essentially that concept
managed automatically by the compiler, for every single type. And at
zero cost for types that do not require clean up. Arguably one of the
most powerful concepts in C++! :)

-Howard
 
P

Phlip

christopher said:
What I am trying to answer is, what the most prominent motivation for
implenting and using smart pointers in C++ is.

Others will answer your inner question well. Here's the outer answer:

If you entered a mainframe computer room in the late 1980s, you would go up
a couple steps. The refrigerated room would contain several clean,
accessible computers, with twinkling lights and dumb terminals at desks.
Everything would be clearly accessible, comprehensible, and labeled. To add
a program to Mainframe B, you sit at the B terminal, and enter 2 to 300
commands in JCL, and the program would run.

However, there's a reason you went up a couple steps. If you get down, and
pull up one of the white floor panels, you would see a little crawl-space.
Peering inside, you'd see endless nameless wires and tubes, snaking this way
and that. None of them would be labelled, or accessible, or neatly arranged.

Some languages build-in their crawlspace, where all the actual plumbing is.

C++ provides mechanisms for the crawlspace, but doesn't provide it or
require it. Other languages simply don't even let you pull up the floor
panels.

In C++, you are expected to build your own crawlspace for each project.
Below it, about 5% of your code is ugly sinister terse and inaccessible. It
looks like endless tubes and wires snaking here and there. Above it are
clean simple accessible objects, all clearly labeled, and easy to use.
 
C

christopher diggins

lilburne said:
How does the last reference to a reference counted pointer
becoming unused, differ from explicitely deleting a pointer
when it is no longer used?

1)
free(dumb_ptr); // explicit deletion

2)
smart_ptr = null; // object might get deleted, it might not, depends on
whether there are other references or not

Does that make it clearer?
 
P

Phlip

christopher said:
1)
free(dumb_ptr); // explicit deletion

2)
smart_ptr = null; // object might get deleted, it might not, depends on
whether there are other references or not

Does that make it clearer?

What if the destructor had side-effects?

For example, what if the destructor restored the mouse pointer state from an
hourglass to a pointer?
Christopher Diggins
yet another language designer

Are we missing something here? ;-)
 
C

Cy Edmunds

Phlip said:
Others will answer your inner question well. Here's the outer answer:

[snip]

Yeah, it was "out there" all right. I think yer losin it Philip... lol
 
E

E. Mark Ping

The RAII (Resource Aquisition Is Initialization) idiom is used here
but it's used in more than just this - it's also used for mutexes for
example. It's probably one of the cornerstones of the language
because if you use it correctly - it's really easy to write
maintainable code.

Indeed, it's used for *lifetime* management, which is the focus of the
RAII model, and which is only partially realted to memory. Memory is
just one resource that needs to be managed, and is indeed one of the
less scarce resources today. OS resources such as synchronization
primatives, UI widgets, etc. all can be used with the RAII idiom (and
often in C++ via smart pointers).
 
L

lilburne

christopher said:
1)
free(dumb_ptr); // explicit deletion

2)
smart_ptr = null; // object might get deleted, it might not, depends on
whether there are other references or not

Does that make it clearer?

Not really all you have done is show the syntax, not the difference in
intent. Never mind.

Our motivation for using smart pointers is primarily a concern about
memory leaks, particularly when ownership of data is passed between
objects, but also including the ommission of a delete in destructors,
and non-cleanup of pointers due to early returns, and breaking out of
loops etc.

However, some of our objects also share instances of other objects. For
example a curve that limits a geometric plane may also be used to limit
a cylinder that punches through the plane. In these cases we use
referenced counted pointers, so that the plane or cylinder can be
removed independently, and the limiting curve gets deleted when its last
usage goes away. For a programmer to track when that occurs and
explicitly call free or delete at the right time, would require tacking
the number of references which is exacly what the smart pointer
encapsulates. Therefore to your question:

"The motivating question is : do C++ programmers / software
designers perceive any advantages to explicitly deallocating
memory over implicitly deallocating memory when the last reference
is used?"

my answer would be no.

BTW We standardize on reference counted pointers for both situations.
 
C

christopher diggins

lilburne said:
Not really all you have done is show the syntax, not the difference in
intent. Never mind.

My point was that case 1 has a clear intent. While case 2 has two potential
intents, delete the reference, delete the object.
Our motivation for using smart pointers is primarily a concern about
memory leaks, particularly when ownership of data is passed between
objects, but also including the ommission of a delete in destructors,
and non-cleanup of pointers due to early returns, and breaking out of
loops etc.

However, some of our objects also share instances of other objects. For
example a curve that limits a geometric plane may also be used to limit
a cylinder that punches through the plane. In these cases we use
referenced counted pointers, so that the plane or cylinder can be
removed independently, and the limiting curve gets deleted when its last
usage goes away. For a programmer to track when that occurs and
explicitly call free or delete at the right time, would require tacking
the number of references which is exacly what the smart pointer
encapsulates. Therefore to your question:

"The motivating question is : do C++ programmers / software
designers perceive any advantages to explicitly deallocating
memory over implicitly deallocating memory when the last reference
is used?"

my answer would be no.

BTW We standardize on reference counted pointers for both situations.

Good clean answer, thank you. If I may further inquire, do these kinds of
design scenarios occur often and does using a smart pointer significantly
improve the elegance of the design?
 
C

christopher diggins

Phlip said:
What if the destructor had side-effects?
For example, what if the destructor restored the mouse pointer state from an
hourglass to a pointer?
Are we missing something here? ;-)


I am sorry I don't understand your question. I don't see what destructor
side effects has to do with this?
 
L

lilburne

christopher said:
My point was that case 1 has a clear intent. While case 2 has two potential
intents, delete the reference, delete the object.


I don't see 'smart_ptr = null;' as deleting either the
underlaying pointer or the smart pointer object. What it
does is make that particular smart pointer instance point to
null. As such it is no different from assigning one smart
pointer to another as in 'smart_ptr1 = smart_ptr2;', or
'smart_ptr = new myClass;'. Whether an object is deleted as
a result isn't of importance, except that there is a
guarantee that it will be when its final smart pointer is
destructed. Of course the symantics of doing the same with
Good clean answer, thank you. If I may further inquire, do these kinds of
design scenarios occur often and does using a smart pointer significantly
improve the elegance of the design?


For us smart pointers often figure in the design, sometimes
because data is semi-permenantly shared amongst object, as
outlined with curves and surfaces. Other times the sharing
is transitory. For example geometry is calculated and then
refined so that only certain bits are kept. Requiring the
programmer to keep track of usage would add an extra level
of complexity into functions that are primarily geometric in
nature.
 

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

Members online

Forum statistics

Threads
473,744
Messages
2,569,480
Members
44,900
Latest member
Nell636132

Latest Threads

Top