[smart_ptr]intrusive_ptr suggestion
Hello all, probably not a good time to post during the stress of 1.44 release. We use boost a lot and also the intrusive_ptr to wrap ref counted objects. However the intuitive behavior gives memory leaks. For example use a ref counted object KFoo: intrusive_ptr<IFoo> ptr(new KFoo); // mleak, KFoo is extra ref counted ptr.reset(new KFoo) //mleak ptr = intrusive_ptr<IFoo>(new KFoo, false); //ok, but Spartan way of writing Above examples are all in contrast with the syntax of shared_ptr's, in which one could write it in above way without leaking. Although the constructor of intrusive_ptr has an extra argument, its default is set on true. Wouldn't it be a nice suggestion to create a function like make_intrusive, so that one could write: ptr = make_intrusive<KFoo>(); It seems so basic that there must be a hidden caveat somewhere...
AMDG gast128 wrote:
We use boost a lot and also the intrusive_ptr to wrap ref counted objects. However the intuitive behavior gives memory leaks. For example use a ref counted object KFoo:
intrusive_ptr<IFoo> ptr(new KFoo); // mleak, KFoo is extra ref counted ptr.reset(new KFoo) //mleak
ptr = intrusive_ptr<IFoo>(new KFoo, false); //ok, but Spartan way of writing
Perhaps you should initialize the reference count to zero in the constructor of IFoo, instead of initializing it to 1. In Christ, Steven Watanabe
<snip>
Perhaps you should initialize the reference count to zero in the constructor of IFoo, instead of initializing it to 1.
In Christ, Steven Watanabe
Yes but I think it is more natural that the ref count starts at 1 for a ref counted object. Thats at least the COM protocol
On August 11, 2010 5:35 PM, gast128 wrote:
<snip>
Perhaps you should initialize the reference count to zero in the constructor of IFoo, instead of initializing it to 1.
In Christ, Steven Watanabe
Yes but I think it is more natural that the ref count starts at 1 for a ref counted object. Thats at least the COM protocol
It's a slightly different situation. COM is designed for manual reference counting. It assumes that each raw pointer, including the one returned from the constructor, counts as a reference. For boost intrusive pointers, the count is the number of intrusive pointers referencing the object. Until you assign the object to one, that count is zero.
Andrew Holden
On August 11, 2010 5:35 PM, gast128 wrote:
<snip>
Perhaps you should initialize the reference count to zero in the constructor of IFoo, instead of initializing it to 1.
In Christ, Steven Watanabe
Yes but I think it is more natural that the ref count starts at 1 for a
ref counted object. Thats at least the
COM protocol
It's a slightly different situation. COM is designed for manual reference counting. It assumes that each raw pointer, including the one returned from the constructor, counts as a reference. For boost intrusive pointers, the count is the number of intrusive pointers referencing the object. Until you assign the object to one, that count is zero.
Not sure if this adresses my problem. intrusive_ptr is used in situations where the object or some other mechanism keeps tracking of its lifetime. intrusive_ptr only guarantees to call 'intrusive_ptr_add_ref' and 'intrusive_ptr_release' on construction and destruction of the intrusive_ptr. The most used scenario is probably objects which are ref counted. The count doesn't need to be the number of intrusive_ptr's on the object; it can be larger than that. Objects which start with a ref count of 1 get the previously described problem. Afaik is that also the most used scenario. Objects with reference count of 0 shouldnt be alive.
On Thu, Aug 12, 2010 at 10:56 AM, gast128
Andrew Holden
writes: On August 11, 2010 5:35 PM, gast128 wrote:
<snip>
Perhaps you should initialize the reference count to zero in the constructor of IFoo, instead of initializing it to 1.
In Christ, Steven Watanabe
Yes but I think it is more natural that the ref count starts at 1 for a
ref counted object. Thats at least the
COM protocol
It's a slightly different situation. COM is designed for manual reference counting. It assumes that each raw pointer, including the one returned from the constructor, counts as a reference. For boost intrusive pointers, the count is the number of intrusive pointers referencing the object. Until you assign the object to one, that count is zero.
Not sure if this adresses my problem. intrusive_ptr is used in situations where the object or some other mechanism keeps tracking of its lifetime. intrusive_ptr only guarantees to call 'intrusive_ptr_add_ref' and 'intrusive_ptr_release' on construction and destruction of the intrusive_ptr. The most used scenario is probably objects which are ref counted. The count doesn't need to be the number of intrusive_ptr's on the object; it can be larger than that.
Objects which start with a ref count of 1 get the previously described problem. Afaik is that also the most used scenario. Objects with reference count of 0 shouldnt be alive.
The ref count is a count of *references* - how many pointers point to
it, whether they are intrusive_ptrs or others:
KFoo * k = new KFoo; k.ref++; //there is one pointer referencing
it, manually update count
intrusive_ptr<KFoo> ik = k; // there are 2 pointers referencing it,
automatically update count
(void) new KFoo; // there are 0 pointers referencing it, count
should be 0 (and obviously we have a leak)
having said that, I agree a wrapper for new would be nice - in
particular one that returned a smart pointer:
intrusive_ptr<KFoo> ik2 = new_intrusive<KFoo>(); // returns
intrusive_ptr, count is 1
(void)new_intrusive<KFoo>(); // returns intrusive, not assigned to
variable, so returned temp goes out of scope - no leak
the problem is with constructor args. ie what if KFoo constructor takes params:
new KFoo(a,b,c);
new_intrusive<KFoo>(a,b,c);
this can be done with templates, but you run into "the forwarding
problem" (google it). C++0x should fix that.
If we were designing C++ from scratch today, maybe plain ol' new would
return a smart pointer, instead of a raw one.
By the way, What I've done once in the past is put the 'false' in the template:
MyIntrusive
participants (4)
-
Andrew Holden
-
gast128
-
Gottlob Frege
-
Steven Watanabe