Thread overview
Pointer cast to uint and back: segfault
Feb 17, 2006
Frank Benoit
Feb 18, 2006
Frank Benoit
February 17, 2006
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
February 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?


February 18, 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
February 18, 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 :)