Search code examples
delphiruntimedynamic-arrays

Register dynamic array at runtime


When you declare dynamic array you do it like this for instance

var
  MyArray: array of Byte;

This way compiler knows that it has to finalize that variable (array) when it gets out of scope. But I want to have dynamic array declared as a Pointer like this

var
  MyArray: Pointer;

I know how to initialize (set length) to such array on the fly in runtime. The problem is the compiler has no clue that it needs to finalize it. I want to know if there is a way to tell the compiler to finalize that pointer as array when out of scope. I would tell him that when I would initialize the array for the first time.

I know this is a hack and please I don't want to hear that it is not a correct way. I have a very specific wish (problem) and I want to know if that is possible to achieve. I guess it is not as compiler does it with compiler magic.

EDIT:

I wanted to keep the question simple but as some want to know more I will tell more. I don't think it is relavant to the question but anyway, here it goes.

I want to conserve 4 bytes (or 8 on 64 bit sytem) for each record. It is more of a play thing. My idea was to insert a pointer to dynamic array inside the variable record TSimpleData. These kind of records do not accept variables that need finalization. Perfectly clear why. But I wanted to know if there is a way to register for finalization later. I was 99% sure there is no way but there is no harm asking to be 100% sure. Bellow is the relevant code in question. I want FComplexData to be a part of TSimpleData as a simple pointer.

 TSimpleData = record { do not pack this record; it is compiler-generated }
    case Byte of
      atInteger:   (VInteger: Integer);
      atCardinal:  (VCardinal: Cardinal);
      atBoolean:   (VBoolean: Boolean);
      atObject:    (VObject: TObject);
      atPointer:   (VPointer: Pointer);
      atClass:     (VClass: TClass);
      atWideChar:  (VWideChar: WideChar);
      atChar:      (VChar: AnsiChar);
    {$IFDEF AnyValue_UseLargeNumbers}
      atInt64:     (VInt64: Int64);
      atExtended:  (VExtended: Extended);
    {$ENDIF}   
  end;

  TAnyValue = packed record   private
    FValueType: TValueType;   
  {$IFNDEF AnyValue_NoInterfaces}
    FInterface: IInterface;   
  {$ENDIF}
    FSimpleData: TSimpleData;
    FComplexData: array of Byte;
    ...    
  end;

Solution

  • To answer my own question, there is no straightforward way to do this. But as I don't give up easily a solution was made:

    http://www.cromis.net/blog/2013/02/tanyvalue-an-attempt-to-make-the-best-variable-data-container/

    It basically does what Embarcadero or Borland should have done ages ago.