New and Delete
The different operators New (Implicit/Overload/Expression/Placement) and Delete (Implicit/Overload/Statement), and all their array-versions New[] and Delete[]
Definition
There may be confusion in the user mind between the different operators New and Delete (despite the documentation that distinguishes them from each other through some different pages):
- 'Operator New Implicit' (inaccessible by user):
- Operator New Overload:
- 'Operator Delete Implicit' (inaccessible by user):
- Operator Delete Overload:
- Operator New Expression:
- Operator Delete Statement:
- Operator Placement New:
- It is a static function that only allocates memory (it is not very different from Allocate).
- It is a member operator (static function) that can overload the 'Operator New Implicit' only for user-defined types.
- So the user can define its own dynamic memory allocation process part (the following process part for implicit data construction can not be modified).
- So the user can define its own dynamic memory allocation process part (the following process part for implicit data construction can not be modified).
- It is a static sub that only frees the memory (it is not very different from Deallocate).
- It is a member operator (static sub) that can overload the 'Operator Delete Implicit' only for user-defined types.
- So the user can define its own memory deallocation process part (the previous process part for implicit data destruction can not be modified).
- So the user can define its own memory deallocation process part (the previous process part for implicit data destruction can not be modified).
- It starts by using the 'Operator New Implicit/Overload' (the implicit, or the overload if exists) to allocate memory.
- Then it invokes the constructor for the right type of object. If that object contains any other objects (either embedded or as base types) those constructors as invoked as well.
- So the final result is memory allocated and object constructed.
- This operator applies to pre-defined types (except fixed-length strings) as well as user-defined types.
- Then it invokes the constructor for the right type of object. If that object contains any other objects (either embedded or as base types) those constructors as invoked as well.
- So the final result is memory allocated and object constructed.
- This operator applies to pre-defined types (except fixed-length strings) as well as user-defined types.
- It starts by invoking the destructor for the right type of object. If that object contains any other objects (either embedded or as base types) those destructors as invoked as well.
- Then it uses the 'Operator Delete Implicit/Overload' (the implicit, or the overload if exists) to deallocate memory.
- So the final result is object destroyed and memory freed.
- This operator applies to pre-defined types (except fixed-length strings) as well as user-defined types.
- Then it uses the 'Operator Delete Implicit/Overload' (the implicit, or the overload if exists) to deallocate memory.
- So the final result is object destroyed and memory freed.
- This operator applies to pre-defined types (except fixed-length strings) as well as user-defined types.
- It only constructs object at a specified memory address (already allocated). This operator applies to pre-defined types (except fixed-length strings) as well as user-defined types.
Instances created with 'Operator New Overload/Expression' must be freed with 'Operator Delete Overload/Statement'.
Instance array created with 'Operator New[] Overload/Expression' must be freed with 'Operator Delete[] Overload/Statement', the array-version of 'Operator Delete Overload/Statement'.
User can not mix and match the different versions of the operators.
Instances constructed at a specified memory address with 'Operator Placement New' must never induce a symmetric freeing with any 'Operator Delete' on the address (because the memory has been allocated in another way than by the 'Operator Placement New').
Instance array constructed at a specified memory address with 'Operator Placement New[]' must never induce a symmetric freeing with any 'Operator Delete[]' on the address (because the memory has been allocated in another way than by the 'Operator Placement New[]').
For such UDT instances, the proper way to just destroy each instance if necessary, is to call only the destructor if one exists (implicitly or explicitly), with syntax as for a member method by using member access operator.
Note: Any operators 'New[]' or 'Delete[]' (the array versions for statement/expression/overload operators) and even the overload operator 'Delete' are not directly compatible with inheritance polymorphism (sub-type polymorphism), because the use of a sub-type pointer (instead of the real type) mainly fails for accessing the other elements (except the first).
Algorithm (applied to user-defined types)
Operator New/New[] Expression:
' OPERATOR NEW/NEW[] EXPRESSION ' V ' | ' call if there is >----------------------------. ' else : ' v v ' (Operator New/New[] Implicit) (Operator New/New[] Overload) ' : : ' BASIC MEMORY ALLOCATION USER BODY for memory allocation ' : : ' :<-------------------------------------' ' | ' |<-------------------------------------. ' | : ' DATA FIELDS INITIALIZATION : ' OBJECT FIELDS CONSTRUCTION : ' (VPTR INITIALIZATION) : ' | : ' call if there is >-----------. : ' else : : ' v v : ' : (User Constructor) : ' : : : ' : USER BODY : ' : : : ' :<--------------------' : ' | : ' loop if array-version NEW[] >-----------------------' ' else ' v ' | ' V
Operator Delete/Delete[] Statement:
' OPERATOR DELETE/DELETE[] STATEMENT ' V ' | ' |<-------------------------------------. ' | : ' (VPTR REINITIALIZATION) : ' | : ' call if there is >-----------. : ' else : : ' v v : ' : (User Destructor) : ' : : : ' : USER BODY : ' : : : ' :<--------------------' : ' | : ' OBJECT FIELDS DESTRUCTION : ' | : ' loop if array-version DELETE[] >---------------------' ' else ' v ' | ' call if there is >----------------------------. ' else : ' v v ' (Operator Delete/Delete[] Implicit) (Operator Delete/Delete[] Overload) ' : : ' BASIC MEMORY DEALLOCATION USER BODY for memory deallocation ' : : ' :<-------------------------------------' ' | ' V
Operator Placement New/New[]:
Example' OPERATOR PLACEMENT NEW/NEW[] ' V ' | ' |<-------------------------------------. ' | : ' DATA FIELDS INITIALIZATION : ' OBJECT FIELDS CONSTRUCTION : ' (VPTR INITIALIZATION) : ' | : ' call if there is >-----------. : ' else : : ' v v : ' : (User Constructor) : ' : : : ' : USER BODY : ' : : : ' :<--------------------' : ' | : ' loop if array-version NEW[] >-----------------------' ' else ' v ' | ' V
Example that uses the operators New (Overload/Expression/Placement) and Delete (Overload/Statement), and all their array-versions New[] and Delete[]:
(all the 10 operators New and Delete accessible by the user):
See also(all the 10 operators New and Delete accessible by the user):
Declare Sub printArray (ByRef label As String = "", array() As String)
Type UDT
Declare Constructor ()
Declare Destructor ()
Declare Operator New (ByVal size As UInteger) As Any Ptr ' Operator New Overload
Declare Operator New[] (ByVal size As UInteger) As Any Ptr ' Operator New[] Overload
Declare Operator Delete (ByVal buf As Any Ptr) ' Operator Delete Overload
Declare Operator Delete[] (ByVal buf As Any Ptr) ' Operator Delete[] Overload
Dim As String array (1 To 4)
End Type
Constructor UDT ()
Static As Integer n
Print " Constructor"
printArray(" init: @" & @This & " (descriptors) -> ", This.array())
For i As Integer = LBound(This.array) To UBound(This.array)
This.array(i) = Chr(Asc("a") + n + i - LBound(This.array))
Next i
printArray(" => ", This.array())
Print
n += UBound(This.array)- LBound(This.array) + 1
End Constructor
Destructor UDT ()
Print " Destructor"
printArray(" erase: @" & @This & " (descriptors) -> ", This.array())
Erase This.array
printArray(" => ", This.array())
Print
End Destructor
Operator UDT.New (ByVal size As UInteger) As Any Ptr
Print " Operator New Overload"
Dim As Any Ptr p = Allocate(size) ' Memory allocation (with passed size)
Print " memory allocation: ";
Print size & " Bytes from @" & p
Return p ' Returning memory pointer
End Operator
Operator UDT.New[] (ByVal size As UInteger) As Any Ptr
Print " Operator New[] Overload"
Dim As Any Ptr p = Allocate(size) ' Memory allocation (with passed size)
Print " memory allocation: ";
Print size & " Bytes from @" & p
Return p ' Returning memory pointer
End Operator
Operator UDT.Delete (ByVal buf As Any Ptr)
Print " Operator Delete Overload"
Deallocate(buf) ' Memory deallocation (with passed pointer)
Print " memory deallocation: ";
Print "for @" & buf
End Operator
Operator UDT.Delete[] (ByVal buf As Any Ptr)
Print " Operator Delete[] Overload"
Deallocate(buf) ' Memory deallocation (with passed pointer)
Print " memory deallocation: ";
Print "for @" & buf
End Operator
Print "Operator New Expression"
Dim As UDT Ptr pu1 = New UDT ' Operator New Expression
Print "Operator Delete Statement"
Delete pu1 ' Operator Delete Statement
Sleep
Print
Print "Operator New[] Expression"
Dim As UDT Ptr pu2 = New UDT[2] ' Operator New[] Expression
Print "Operator Delete[] Statement"
Delete[] pu2 ' Operator Delete[] Statement
Sleep
Dim As Byte buffer(1 To 256)
Dim As Any Ptr p = @buffer(1)
Print
Print "Operator Placement New"
Dim As UDT Ptr pu3 = New(p) UDT ' Operator Placement New
Print "User call of Destructor"
pu3->Destructor() ' User Call of Destructor
Sleep
Print
Print "Operator Placement New[]"
Dim As UDT Ptr pu4 = New(p) UDT[2] ' Operator Placement New[]
For i As Integer = 0 To 1
Print "User Call of Destructor"
pu4[i].Destructor() ' User Call of Destructor
Next i
Sleep
Sub printArray (ByRef label As String = "", array() As String)
Print label & "{";
For i As Integer = LBound(array) To UBound(array)
Print """" & array(i) & """";
If i < UBound(array) Then
Print ",";
End If
Next I
Print "}";
End Sub
Output example (for a 64-bit system):Type UDT
Declare Constructor ()
Declare Destructor ()
Declare Operator New (ByVal size As UInteger) As Any Ptr ' Operator New Overload
Declare Operator New[] (ByVal size As UInteger) As Any Ptr ' Operator New[] Overload
Declare Operator Delete (ByVal buf As Any Ptr) ' Operator Delete Overload
Declare Operator Delete[] (ByVal buf As Any Ptr) ' Operator Delete[] Overload
Dim As String array (1 To 4)
End Type
Constructor UDT ()
Static As Integer n
Print " Constructor"
printArray(" init: @" & @This & " (descriptors) -> ", This.array())
For i As Integer = LBound(This.array) To UBound(This.array)
This.array(i) = Chr(Asc("a") + n + i - LBound(This.array))
Next i
printArray(" => ", This.array())
n += UBound(This.array)- LBound(This.array) + 1
End Constructor
Destructor UDT ()
Print " Destructor"
printArray(" erase: @" & @This & " (descriptors) -> ", This.array())
Erase This.array
printArray(" => ", This.array())
End Destructor
Operator UDT.New (ByVal size As UInteger) As Any Ptr
Print " Operator New Overload"
Dim As Any Ptr p = Allocate(size) ' Memory allocation (with passed size)
Print " memory allocation: ";
Print size & " Bytes from @" & p
Return p ' Returning memory pointer
End Operator
Operator UDT.New[] (ByVal size As UInteger) As Any Ptr
Print " Operator New[] Overload"
Dim As Any Ptr p = Allocate(size) ' Memory allocation (with passed size)
Print " memory allocation: ";
Print size & " Bytes from @" & p
Return p ' Returning memory pointer
End Operator
Operator UDT.Delete (ByVal buf As Any Ptr)
Print " Operator Delete Overload"
Deallocate(buf) ' Memory deallocation (with passed pointer)
Print " memory deallocation: ";
Print "for @" & buf
End Operator
Operator UDT.Delete[] (ByVal buf As Any Ptr)
Print " Operator Delete[] Overload"
Deallocate(buf) ' Memory deallocation (with passed pointer)
Print " memory deallocation: ";
Print "for @" & buf
End Operator
Print "Operator New Expression"
Dim As UDT Ptr pu1 = New UDT ' Operator New Expression
Print "Operator Delete Statement"
Delete pu1 ' Operator Delete Statement
Sleep
Print "Operator New[] Expression"
Dim As UDT Ptr pu2 = New UDT[2] ' Operator New[] Expression
Print "Operator Delete[] Statement"
Delete[] pu2 ' Operator Delete[] Statement
Sleep
Dim As Byte buffer(1 To 256)
Dim As Any Ptr p = @buffer(1)
Print "Operator Placement New"
Dim As UDT Ptr pu3 = New(p) UDT ' Operator Placement New
Print "User call of Destructor"
pu3->Destructor() ' User Call of Destructor
Sleep
Print "Operator Placement New[]"
Dim As UDT Ptr pu4 = New(p) UDT[2] ' Operator Placement New[]
For i As Integer = 0 To 1
Print "User Call of Destructor"
pu4[i].Destructor() ' User Call of Destructor
Next i
Sleep
Sub printArray (ByRef label As String = "", array() As String)
Print label & "{";
For i As Integer = LBound(array) To UBound(array)
Print """" & array(i) & """";
If i < UBound(array) Then
Print ",";
End If
Next I
Print "}";
End Sub
Operator New Expression Operator New Overload memory allocation: 96 Bytes from @1728352 Constructor init: @1728352 (descriptors) -> {"","","",""} => {"a","b","c","d"} Operator Delete Statement Destructor erase: @1728352 (descriptors) -> {"a","b","c","d"} => {"","","",""} Operator Delete Overload memory deallocation: for @1728352
Operator New[] Expression Operator New[] Overload memory allocation: 200 Bytes from @1728352 Constructor init: @1728360 (descriptors) -> {"","","",""} => {"e","f","g","h"} Constructor init: @1728456 (descriptors) -> {"","","",""} => {"i","j","k","l"} Operator Delete[] Statement Destructor erase: @1728456 (descriptors) -> {"i","j","k","l"} => {"","","",""} Destructor erase: @1728360 (descriptors) -> {"e","f","g","h"} => {"","","",""} Operator Delete[] Overload memory deallocation: for @1728352
Operator Placement New Constructor init: @1375248 (descriptors) -> {"","","",""} => {"m","n","o","p"} User call of Destructor Destructor erase: @1375248 (descriptors) -> {"m","n","o","p"} => {"","","",""}
Operator Placement New[] Constructor init: @1375248 (descriptors) -> {"","","",""} => {"q","r","s","t"} Constructor init: @1375344 (descriptors) -> {"","","",""} => {"u","v","w","x"} User Call of Destructor Destructor erase: @1375248 (descriptors) -> {"q","r","s","t"} => {"","","",""} User Call of Destructor Destructor erase: @1375344 (descriptors) -> {"u","v","w","x"} => {"","","",""}
- Operator
- Constructor
- Destructor
- Use Implicit / Overload New([]) and Delete([]) Operators with Inheritance Polymorphism
Back to Programmer's Guide