www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Crash writing and reading back class instance address to void*

reply "Remi Thebault" <remi.thebault outlook.com> writes:
Hi

Starting to use GtkD TreeModel, I write an instance of an 
abstract class to TreeIter.userData.

When reading back the void pointer and casting to my abstract 
class leads to crash when instance is used (Task is the abstract 
class):


         int fillIter(TreeIter iter, Task t)
         {
             if (!t || !iter) return 0;

             iter.stamp = stamp_;

             writeln("writing ", cast(void*)&t);
             iter.userData = cast(void*)&t;

             return 1;
         }


         Task taskFromIter(TreeIter iter)
         {
             if (!iter || iter.stamp != stamp_) return null;

             writeln("reading ", iter.userData);
             writeln(cast(Task)iter.userData);
             return cast(Task)iter.userData;
         }

the code prints
writing 18FC98
reading 18FC98

and crashes at the 2nd writeln call in taskFromIter function with 
message object.Error (0): Access violation

The instance is referenced somewhere else in the model, so it 
should not get garbage collected. should I check this anyway?

Any idea?

thanks
Rémi
Aug 18 2014
parent reply "FreeSlave" <freeslave93 gmail.com> writes:
On Monday, 18 August 2014 at 10:07:30 UTC, Remi Thebault wrote:
 Hi

 Starting to use GtkD TreeModel, I write an instance of an 
 abstract class to TreeIter.userData.

 When reading back the void pointer and casting to my abstract 
 class leads to crash when instance is used (Task is the 
 abstract class):


         int fillIter(TreeIter iter, Task t)
         {
             if (!t || !iter) return 0;

             iter.stamp = stamp_;

             writeln("writing ", cast(void*)&t);
             iter.userData = cast(void*)&t;

             return 1;
         }


         Task taskFromIter(TreeIter iter)
         {
             if (!iter || iter.stamp != stamp_) return null;

             writeln("reading ", iter.userData);
             writeln(cast(Task)iter.userData);
             return cast(Task)iter.userData;
         }

 the code prints
 writing 18FC98
 reading 18FC98

 and crashes at the 2nd writeln call in taskFromIter function 
 with message object.Error (0): Access violation

 The instance is referenced somewhere else in the model, so it 
 should not get garbage collected. should I check this anyway?

 Any idea?

 thanks
 Rémi
Classes are reference types. You take reference of local reference (it's address on stack). Use just cast(void*)t
Aug 18 2014
parent "Remi Thebault" <remi.thebault outlook.com> writes:
 Classes are reference types. You take reference of local 
 reference (it's address on stack). Use just cast(void*)t
Thank you!
Aug 18 2014