Topic: auto_ptr as a return value


Author: andru123@hotmail.com
Date: Wed, 24 Aug 2005 10:41:12 CST
Raw View
Hi,


auto_ptr<Bla> makeBla()
{
 return NULL;
}

//Assuming auto_ptr is OWNER of the objects, I MUST call release()
auto_ptr<Bla> bla = makeBla().release();


As you can guess, here i get an exception.

Can I do this then:

auto_ptr<Bla> bla = NULL;
if (makeBla() != NULL)
{
 bla = makeBla();
}

My question:
will the result of the first call of makeBla() be deleted/ handled
correctly?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: clarkcox3@gmail.com ("Clark S. Cox III")
Date: Wed, 24 Aug 2005 19:52:09 GMT
Raw View
On 2005-08-24 06:41:12 -0400, andru123@hotmail.com said:

> auto_ptr<Bla> makeBla()
> {
>  return NULL;
> }

First, auto_ptr's constructor is explicit, which means that NULL will
not be implicitly converted in this case (I'm assuming that in your
real code, you're returning an actual object.

> //Assuming auto_ptr is OWNER of the objects, I MUST call release()
> auto_ptr<Bla> bla = makeBla().release();

You don't have to do that at all. The assignment operator and copy
constructor of auto_ptr both transfer the ownership of the contained
pointer:

[littleclark2:~] clarkcox% cat test.cpp
#include <memory>
#include <iostream>

using namespace std;

struct Foo
{
  Foo() { std::cout << "Foo::Foo() called.\n"; }
  ~Foo() { std::cout << "Foo::~Foo() called.\n"; }
};

auto_ptr<Foo> makeBla()
{
  return auto_ptr<Foo>(new Foo);
}

int main()
{
  auto_ptr<Foo> a = makeBla();
  Foo           *raw = a.get();
  assert(a.get() == raw);

  auto_ptr<Foo> b = a;
  assert(a.get() == NULL);
  assert(b.get() == raw);


  auto_ptr<Foo> c;
  c = b;
  assert(a.get() == NULL);
  assert(b.get() == NULL);
  assert(c.get() == raw);

  std::cout  << "a, b and c are about to go out of scope.\n";
  return 0;
}

[littleclark2:~] clarkcox% c++ test.cpp && ./a.out
Foo::Foo() called.
a, b and c are about to go out of scope.
Foo::~Foo() called.

[littleclark2:~] clarkcox%


>
>
> As you can guess, here i get an exception.
>
> Can I do this then:
>
> auto_ptr<Bla> bla = NULL;
> if (makeBla() != NULL)
> {
>  bla = makeBla();
> }
>
> My question:
> will the result of the first call of makeBla() be deleted/ handled
> correctly?

Yes, it will be deleted when the unnamed, temporary auto_ptr is
destructed, however, as I explained above, your problem is elsewhere,
as auto_ptr is explicitly designed to handle this case.


--
Clark S. Cox, III
clarkcox3@gmail.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "thoth39" <pedro.lamarao@gmail.com>
Date: Wed, 24 Aug 2005 14:51:28 CST
Raw View
> //Assuming auto_ptr is OWNER of the objects, I MUST call release()
> auto_ptr<Bla> bla = makeBla().release();

Why not:

auto_ptr<Bla> bla = makeBla();

?

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Michael.Karcher@writeme.com (Michael Karcher)
Date: Thu, 25 Aug 2005 02:43:31 GMT
Raw View
andru123@hotmail.com wrote:
> Hi,
>
>
> auto_ptr<Bla> makeBla()
> {
>  return NULL;
> }
>
> //Assuming auto_ptr is OWNER of the objects, I MUST call release()
> auto_ptr<Bla> bla = makeBla().release();

No, you do not need to call release to transfer ownership from one
auto_ptr to another auto_ptr. Assignment and copy construction (this
also applies to copy-construction for by-value-arguments, a common
auto_ptr pitfall) do _always_ transfer ownership. So you should just write

  auto_ptr<Bla> bla = makeBla();

or, equivalently

  auto_ptr<Bla> bla(makeBla());

> Can I do this then:
>
> auto_ptr<Bla> bla = NULL;
> if (makeBla() != NULL)
> {
>  bla = makeBla();
> }
>
> My question:
> will the result of the first call of makeBla() be deleted/ handled
> correctly?

You can do this, but the line inside the if construct does not call
release, so it works even if the result of makeBla is NULL. The result
of the first call will be handled correctly, as this is the point of
auto_ptr. If an auto_ptr is destroyed still having a pointee, it is
deleted. The first call creates a temporary auto_ptr object, where the
full-expression it is in is the condition of the if statement. After
evalutating this expression, all temporaries that are not bound to references
by that expression, are deleted.

Your example will of course *not* do what you intend if makeBla sometimes
returns NULL and sometimes a valid pointer depending on external state that
may change between the two calls.

Michael Karcher

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]