Qt-interest Archive, February 2007
QSharedDataPointer problems - destructor called more than once?
Message 1 in thread
Hi all. Having the following issue, which seems to happen
inconsistently.
I have a QSharedDataPointer that points to an object that inherits
QSharedData. I'm emitting a signal that contains the pointer as
follows:
emit mySignal( QSharedDataPointer< MyData >( new MyData() ) );
On the receiving end, I have a slot that takes the pointer:
mySlot( QSharedDataPointer< MyData > );
For some reason, on occasion, I notice that ~MyData() gets called
twice, which corrupts memory, because MyData has a pointer member
that points to a single memory location (and must do so).
Does emitting this as a signal result in a detach() somewhere that
gives us this behavior? If so, then why is this only happening on
occasion?
Is there a better approach to what I'm trying to accomplish - I'd
like for several objects who deal with this data via their slots to
deal with the same data, and for that data only to be destroyed when
1) the slot/signal system has delivered the signal to all the slots
and 2) those slots have finished working with the data. Also the
object that emits the signal is stateless and cannot keep track of
this data itself.
Thanks,
Bruno
Message 2 in thread
So I did a quick experiment. I have a slot accepting the
QSharedDataPointer as an argument. Let's call it:
void MySlot( QSharedDataPointer < MyData > in_d )
The first thing I do is output the ref count:
cout << in_d->ref << endl;
Then I create a new Pointer, passing it the original one:
QSharedDataPointer<MyData> d(in_d); // QSharedDataPointer<MyData> d =
in_d; // <- I've also tried this variation
Then I print out the ref count for both of the two pointers:
cout << in_d->ref << endl;
cout << d->ref << endl;
In all cases, what I see is:
1
1
1
The ref count never increases! Can someone please lend some insight
- I'm stumped and nothing in the docs is clarifying this for me. I'm
uising Qt on Mac OS X (Intel), linked against Qt frameworks.
Thanks,
Bruno
On Feb 2, 2007, at 10:57 AM, Bruno Trindade wrote:
> Hi all. Having the following issue, which seems to happen
> inconsistently.
>
> I have a QSharedDataPointer that points to an object that inherits
> QSharedData. I'm emitting a signal that contains the pointer as
> follows:
>
> emit mySignal( QSharedDataPointer< MyData >( new MyData() ) );
>
> On the receiving end, I have a slot that takes the pointer:
> mySlot( QSharedDataPointer< MyData > );
>
> For some reason, on occasion, I notice that ~MyData() gets called
> twice, which corrupts memory, because MyData has a pointer member
> that points to a single memory location (and must do so).
>
> Does emitting this as a signal result in a detach() somewhere that
> gives us this behavior? If so, then why is this only happening on
> occasion?
>
> Is there a better approach to what I'm trying to accomplish - I'd
> like for several objects who deal with this data via their slots to
> deal with the same data, and for that data only to be destroyed
> when 1) the slot/signal system has delivered the signal to all the
> slots and 2) those slots have finished working with the data. Also
> the object that emits the signal is stateless and cannot keep track
> of this data itself.
>
> Thanks,
> Bruno
>
>
>
>
>
Message 3 in thread
On Friday 02 February 2007 22:19, Bruno Trindade wrote:
> So I did a quick experiment. I have a slot accepting the
> QSharedDataPointer as an argument. Let's call it:
> void MySlot( QSharedDataPointer < MyData > in_d )
>
> The first thing I do is output the ref count:
> cout << in_d->ref << endl;
>
> Then I create a new Pointer, passing it the original one:
> QSharedDataPointer<MyData> d(in_d); // QSharedDataPointer<MyData> d =
> in_d; // <- I've also tried this variation
>
> Then I print out the ref count for both of the two pointers:
> cout << in_d->ref << endl;
> cout << d->ref << endl;
>
> In all cases, what I see is:
> 1
> 1
> 1
>
> The ref count never increases! Can someone please lend some insight
> - I'm stumped and nothing in the docs is clarifying this for me. I'm
> uising Qt on Mac OS X (Intel), linked against Qt frameworks.
>
> Thanks,
> Bruno
>
As the name of the class says, it is a shared data pointer. It basically means
that you will have the same object as long as you don't modify the data. When
you try to modify the shared data object, you get a deep copy of it. In your
case the compiler has no idea that you don't want to modify the data since
you pass it to a function where it could be modified. When you dereference
the pointer, you tell to the compiler that you may want to modify it even if
you don't do it.
The QSharedDataPointer is good for resources that are shared along many users
without ever modifying it, like QFont that stays the same unless you replace
it with something else in the specific widget. One possible option could be
changing your slot functions to take a const QSharedDataPointer argument.
That should tell to the compiler that you will not change the data object in
your function, but I haven't tried that approach myself.
I went another way and implemented my own reference counted objects, which
works perfect for my needs. I can send pointers to my data objects in Qt
events and be sure that they get deleted when nobody needs them anymore.
Might be that you could do the same.
Regards,
Enar
--
[ signature omitted ]
Message 4 in thread
Thanks Enar. I was initially going to create my own smart pointers,
but I didn't want to reinvent the wheel if Qt already offers
something along this line. Also, since I'm just starting to learn
Qt, I thought it worthwhile to invest the time in figuring out how to
use these built-in classes.
I will try the const approach, and if that fails, I'll go with my
custom smart pointers.
Thanks again,
Bruno
On Feb 2, 2007, at 4:54 PM, Enar Väikene wrote:
> On Friday 02 February 2007 22:19, Bruno Trindade wrote:
>> So I did a quick experiment. I have a slot accepting the
>> QSharedDataPointer as an argument. Let's call it:
>> void MySlot( QSharedDataPointer < MyData > in_d )
>>
>> The first thing I do is output the ref count:
>> cout << in_d->ref << endl;
>>
>> Then I create a new Pointer, passing it the original one:
>> QSharedDataPointer<MyData> d(in_d); // QSharedDataPointer<MyData> d =
>> in_d; // <- I've also tried this variation
>>
>> Then I print out the ref count for both of the two pointers:
>> cout << in_d->ref << endl;
>> cout << d->ref << endl;
>>
>> In all cases, what I see is:
>> 1
>> 1
>> 1
>>
>> The ref count never increases! Can someone please lend some insight
>> - I'm stumped and nothing in the docs is clarifying this for me. I'm
>> uising Qt on Mac OS X (Intel), linked against Qt frameworks.
>>
>> Thanks,
>> Bruno
>>
>
> As the name of the class says, it is a shared data pointer. It
> basically means
> that you will have the same object as long as you don't modify the
> data. When
> you try to modify the shared data object, you get a deep copy of
> it. In your
> case the compiler has no idea that you don't want to modify the
> data since
> you pass it to a function where it could be modified. When you
> dereference
> the pointer, you tell to the compiler that you may want to modify
> it even if
> you don't do it.
>
> The QSharedDataPointer is good for resources that are shared along
> many users
> without ever modifying it, like QFont that stays the same unless
> you replace
> it with something else in the specific widget. One possible option
> could be
> changing your slot functions to take a const QSharedDataPointer
> argument.
> That should tell to the compiler that you will not change the data
> object in
> your function, but I haven't tried that approach myself.
>
> I went another way and implemented my own reference counted
> objects, which
> works perfect for my needs. I can send pointers to my data objects
> in Qt
> events and be sure that they get deleted when nobody needs them
> anymore.
> Might be that you could do the same.
>
>
> Regards,
> Enar
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx
> with "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]