Boost logo

Boost :

Subject: Re: [boost] [Container] Inner Smart Pointers
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2016-02-20 01:11:24


AMDG

On 02/19/2016 07:48 PM, Phil Bouchard wrote:
> On 2016-02-19 9:30 PM, Steven Watanabe wrote:
>>
>> On 02/19/2016 05:53 PM, Phil Bouchard wrote:
>>> On 2016-02-18 11:53 PM, Phil Bouchard wrote:
>>>> I have to admit MSVC 2015 got a clean STL...
>>>
>>> Their STL is good but unfortunately they pass their pointer arguments by
>>> value and not by reference so it makes it impossible to use smart
>>> pointers for internal node pointers.
>>>
>>
>> I don't understand how pass-by-value would
>> break smart pointers. I can see that it might
>> be inefficient, but it shouldn't actually fail.
>
> Because the only way to deallocate the content of a smart pointer is by
> deallocating and resetting its pointer to 0, which modifies the pointer.
>
> For example:
>
> 1) The allocator's deallocate function will call p.reset():
>
> <snip>
> 2) In MSVC 2015 the deallocate function is called by this one which has
> a pointer passed by value:
>
> template<class _Alloc>
> struct _Wrap_alloc
> : public _Alloc
> { // defines traits for allocators
> [...]
> void deallocate(pointer _Ptr, size_type _Count)
> { // deallocate object at _Ptr, ignore size
> _Mybase::deallocate(_Ptr, _Count);
> }
>

That isn't specific to MSVC:
[allocator.requirements]:

Table 27: "p a value of type XX::pointer,
obtained by calling a1.allocate, where a1 == a

Table 28: "a.deallocate(p,n)"

p is not required to be an lvalue, here.

[allocator.members]: "void deallocate(pointer p, size_type n);"

(C++11)

>
> 3) Which in turn is called by another one using a parameter passed by
> value:
>
> template<class _Alloc_types>
> class _List_alloc
> { // base class for list to hold allocator
> public:
> [...]
> void _Freeheadnode(_Nodeptr _Pnode)
> { // free head node using current allocator
> _Getal().destroy(
> _STD addressof(_Nextnode(_Pnode)));
> _Getal().destroy(
> _STD addressof(_Prevnode(_Pnode)));
> _Getal().deallocate(_Pnode, 1);
> }
>
> 4) ...
>
>
> The bottom line is resetting a copy of a smart pointer won't do
> anything. This is why it needs to be passed by reference.
>

  You can't deallocate anything, anyway, because there
may be other copies of the pointer. The whole point
of using smart pointers in the first place, is that
the deallocate is run automatically. Just leave allocator.deallocate
as a no-op and let the memory be freed when the pointer
is destroyed or assigned.

In Christ,
Steven Watanabe


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