return *(cast(T*)vPtr) and OutOfMemoryException

TSalm TSalm at free.fr
Sat Feb 14 09:16:12 PST 2009


Excellent explication !
Thank you Frits

Le Sat, 14 Feb 2009 17:58:35 +0100, Frits van Bommel  
<fvbommel at remwovexcapss.nl> a écrit:

> 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