return *(cast(T*)vPtr) and OutOfMemoryException
Frits van Bommel
fvbommel at REMwOVExCAPSs.nl
Sat Feb 14 08:58:35 PST 2009
TSalm wrote:
> Hello,
>
> In the code below, why the first Stdout throws a Exception when the
> second doesn't ?
>
> /* -------- CODE -------- */
> import tango.io.Stdout;
>
>
> struct VoidPtr(T)
> {
> void* vPtr;
>
> void value(T val)
> {
> vPtr = &val;
Here you're storing a pointer to a non-ref parameter. This is the bug;
the parameter itself is implicitly deallocated on returning from this
function.
Change to 'ref T val' to fix it.
Essentially, an array is a struct { size_t length; T ptr; }. This means
'val' refers to a copy in the stack frame of this function, not to 'arr'
in main().
> }
>
> T value()
> {
> return *(cast(T*)vPtr);
> }
> }
>
>
> void main()
> {
> VoidPtr!(char[][]) vPtr ;
>
> char[][] arr = [ "hello" , "you" ];
>
> vPtr.value = arr ;
>
> Stdout( vPtr.value ).newline; // <--
> [tango.core.Exception.OutOfMemoryException: Memory allocation failed
Here you're calling a new function, overwriting *vPtr with something
else (probably vptr itself), resulting in a huge array when you try to
read it later.
>
> Stdout( *(cast(char[][]*) vPtr.vPtr ) ); // <-- This works good
This reads the (implicitly deallocated) 'val' parameter before it gets
overwritten, hiding the bug. It's still there: just because the code
doesn't crash doesn't mean it's correct.
> }
>
> /* ------ END CODE ------ */
>
>
> Thanks in advance for your help,
> TSalm
More information about the Digitalmars-d-learn
mailing list