Boost logo

Boost :

Subject: Re: [boost] [ptr_container] ptr_vector transfer from C array of pointers documentation
From: Thorsten Ottosen (nesotto_at_[hidden])
Date: 2010-07-28 11:36:09


Number Cruncher skrev:
> The documentation for ptr_vector::transfer( iterator before, T** from,
> size_type size, bool delete_from = true ) implies that the operation
> "delete [] from" is executed, but having examined the source, I don't
> think it is. This is actually the behaviour I need.

The docs could be slightly clearer, but I think they are close to optimal.

> I'm trying to convert a std::vector<T*> to a boost::ptr_vector<T*>, i.e.
> I have a vector of pointers which is solely responsible for "owning" the
> objects being pointed to, and I want to create a ptr_vector which will
> automatically clean up the objects when it goes out of scope. I need to
> do the transfer so that no memory leaks in the event of an exception.
>
> As far as I can see, this is exactly what ptr_vector::scoped_deleter is
> doing: it will delete any of the copied pointers, but it never actually
> deletes the "from" pointer; presumably because you don't know whether
> operator new[] was used when allocating it.

Actually it does call delete[] in any case as the destructor of
scoped_deleter will call the destructor of the stored scoped_array
member. scoped_deleter::release() only means that the T* objects are not
deleted, but the internal array always is.

> Can anyone clear up/confirm that this will work:
> std::vector<T*> v1;
> v1.push_back(new T);
>
> boost::ptr_vector<T> v2;
> if (!v1.empty()) {
> v2.transfer(v2.end(), &v1[0], v1.size(), true);
> }
> // from this point, don't care about v1 and v2 will handle deletion of
> T objs

Well, a vector<T*> cannot guarantee that the internal buffer is
allocated with new T[], I would say its almost guaranteed that it is
not. IOW, the function is meant for C-arrays allocated with new T[], not
vectors. So no, it won't work. replacing true with false makes it work,
but ...

You can still get a leak if insertion fails, but how is that any worse
than what your current code can do? Otherwise, use scoped_deleter
manually as so:

  v2.scoped_deleter sd( v2, v1.size() );
  std::copy( v1.begin(), v1.end(), sd.begin() );
  v2.transfer( v2.end(), sd.begin(), v1.size(), false );
  sd.release();

<remark>
It would have been possible to do v1.swap(v2.base()) if it was not for
the use of void* internally. Its on my agenda to change this in the future
</remark>

A question: why don't you just use ptr_vector where it's needed? Is it s
legacy issue?

HTH

-Thorsten


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk