digitalmars.D - Pointer cast to uint and back: segfault
- Frank Benoit (65/65) Feb 17 2006 I have a class which is not managed by the gc. This is done like in the
-
Jarrett Billingsley
(12/12)
Feb 17 2006
"Frank Benoit"
wrote in message - Frank Benoit (16/18) Feb 17 2006 Yes perhaps this would be possible, but in my case this is the straight ...
- Jarrett Billingsley (3/14) Feb 17 2006 Ahh, that makes sense then :)
I have a class which is not managed by the gc. This is done like in the example on http://digitalmars.com/d/memory.html#newdelete Now I need to transfer these object-references through a queue. If I write this: union U { uint val; Cls obj; } // obj -> uint U u; u.obj = obj; queue.push( u.val ); // uint -> obj U u; u.val = queue.get(); u.obj.doSomething(); ... it works excellent. But now i want to make this with directly casting to the right type without the intermediate copy to a union. // obj -> uint queue.push( cast(uint)(&obj) ); // uint -> obj Cls obj = *cast(Cls*)( queue.get() ); obj.doSomething(); // segmentation fault Whats wrong? I am pretty sure my queues are working correctly. //////////////////////////////////////////////////////////////////////// /// The following is a description of further experiments: //////////////////////////////////////////////////////////////////////// ... So I made a little test program: class C { void doIt() { writefln( "yes" ); } } void main(){ C c = new C; uint u = cast(uint)(& c ); ( *cast(C*)(u) ).doIt(); } No segfault. :( Playing with it I get another segmentation fault when I made functions for the casts and inserted a writefln: uint toUint( C c ){ uint r = cast(uint)(& c ); return r; } C toC( uint u ){ return *cast(C*)(u); } void main(){ uint u = toUint( new C ); writefln( "%08x", u ); toC( u ).doIt(); // Segfault } By the way: This compiles uint toUint( C c ){ uint r = cast(uint)(& c ); return r; } This not: uint toUint( C c ){ return cast(uint)(& c ); // escaping reference to local c } Frank -- D goes real-time: http://www.drealtime.com
Feb 17 2006
"Frank Benoit" <frank_DELETE_ _DELETE_drealtime.com> wrote in message news:dt5jp4$p97$1 digitaldaemon.com... Two things. Class references are already at one level of indirection. Taking the address of a class reference won't work the way you think. That's why your functions won't work; that "escaping reference to local" error was trying to help you. You're not returning the address of the object held in c; you're returning the address of a local variable c, which is on the stack and becomes invalid when the function returns. So instead of getting the address, just use cast(uint)cast(void*)new C, and get it back with cast(C)cast(void*)(u). The second thing is I can't figure out why the hell you have to do all this. Can't you make your queue accept class references?
Feb 17 2006
Thanks, that was the cast I was looking for.The second thing is I can't figure out why the hell you have to do all this. Can't you make your queue accept class references?Yes perhaps this would be possible, but in my case this is the straight way, I think. To give you an idea what I am doing. I use a real-time extension for Linux. Threads running in real-time could not allocate dynamic memory. But I want to generate test results. So I use a queue with a fixed size ring buffer. A code generator makes functions for me, doing the encoding of the defined message types. Putting all data in the uint array of the queue. On the other side (in the normal, not-real-time thread) there is also generated code, decoding the data, creating objects with the right type and calling "new" and filling them with the data of the queue. But to pass object through such a queue, they have to be casted to raw data. Thanks for your help Frank -- D goes real-time: http://www.drealtime.com
Feb 17 2006
"Frank Benoit" <frank_DELETE_ _DELETE_drealtime.com> wrote in message news:dt5phm$tk8$1 digitaldaemon.com...To give you an idea what I am doing. I use a real-time extension for Linux. Threads running in real-time could not allocate dynamic memory. But I want to generate test results. So I use a queue with a fixed size ring buffer. A code generator makes functions for me, doing the encoding of the defined message types. Putting all data in the uint array of the queue. On the other side (in the normal, not-real-time thread) there is also generated code, decoding the data, creating objects with the right type and calling "new" and filling them with the data of the queue. But to pass object through such a queue, they have to be casted to raw data.Ahh, that makes sense then :)
Feb 17 2006