NEW operator

Forum for discussion about the documentation project.
Post Reply
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

NEW operator

Post by speedfixer »

because:
The extra uinteger, if allocated, stores the number of elements as part of the allocation ...
and it appears that only one is allocated, it seems that the NEW/DELETE **can't** be used on multi-dimension arrays.
At least, I can't figure out how to make it work.


This should be mentioned in the wiki.

david
fxm
Moderator
Posts: 12141
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: NEW operator

Post by fxm »

I do not see what's your problem.
Can you clarify it, with that would be the best, an example of code?

Example for a 2-dimension array of objects with destructor:

Code: Select all

Type UDT
  Dim As Integer N
  Declare Constructor ()
  Declare Destructor ()
End Type

Constructor UDT ()
  Print "Constructor",
End Constructor

Destructor UDT ()
  Print "Destructor",
End Destructor


Dim As UDT Ptr Ptr p = New UDT Ptr [4]  '' no allocation of extra uinteger, because pointers allocation
For I As Integer = 0 To 3
  p[I] = New UDT [5]  '' allocation of an extra uinteger for each New, because UDT (with destructor) objects allocation
  Print
Next I

For I As Integer = 0 To 3
  For J As Integer = 0 To 4
    p[I][J].N = I * 10 + J
  Next J
Next I

Print
For I As Integer = 0 To 3
  For J As Integer = 0 To 4
    Print p[I][J].N,
  Next J
  Print
Next I
Print


For I As Integer = 0 To 3
  Delete [] p[I]
  Print
Next I
Delete [] p
Print

Sleep
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

Re: NEW operator

Post by speedfixer »

What I tried was:

Code: Select all

type udt1
    ip as integer ptr
    declare constructor()
    declare destructor()
end type

constructor udt1
    ip = new integer[6,6]
end constructor

destructor udt1
    delete [] ip
end destructor

dim as udt1 newvar

'something executable
print
test.bas(9) error 66: Expected ']', found ',' in 'ip = new integer[6,6]'
In reading https://www.freebasic.net/wiki/wikka.ph ... KeyPgOpNew carefully, it says **one** extra uinteger is allocated, not one per dimension. It looks like more than one dimension can't be handled by the NEW/DELETE operations. This should be noted on the wiki page.

Unless you have a way to make it work.

I have already solved my programming problem, but perhaps someone else could benefit from either a solution or some extra text on the wiki.
fxm
Moderator
Posts: 12141
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: NEW operator

Post by fxm »

I added an example of use in my previous post.

I modified your code as follows:

Code: Select all

type udt1
    ip as integer ptr ptr
    declare constructor()
    declare destructor()
end type

constructor udt1
    ip = new integer ptr [6]  '' no allocation of extra uinteger, because integer pointers allocation
    for i as integer = 0 to 5
        ip[i] = new integer [6]  '' no allocation of an extra uinteger for each New, because integers allocation
    next i
end constructor

destructor udt1
    for i as integer = 0 to 5
        delete [] ip[i]
    next i
    delete [] ip
end destructor

dim as udt1 newvar

newvar.ip[3][2] = 32
Print newvar.ip[3][2]

print
See also the documentation page: Operator [] (Pointer index)
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

Re: NEW operator

Post by speedfixer »

Yes, thank you, you solved the problem of expressing a multi-dimension NEW/DELETE.

Now, the wiki should still have the comment added that NEW/DELETE does not support a multi-dimension array, but a solution is possible.
Just include this example to show how to achieve that goal.
fxm
Moderator
Posts: 12141
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: NEW operator

Post by fxm »

What example?
The your updated, or my first?
speedfixer
Posts: 606
Joined: Nov 28, 2012 1:27
Location: CA, USA moving to WA, USA
Contact:

Re: NEW operator

Post by speedfixer »

Your example is less complex than mine. That would be better.
fxm
Moderator
Posts: 12141
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: NEW operator

Post by fxm »

Documentation updated:
- KeyPgOpPlacementNew → fxm [Clarified that New [] is one-dimensional]
- KeyPgOpNewOverload → fxm [Clarified that New [] is one-dimensional]
- KeyPgOpNew → fxm [Clarified that New [] is one-dimensional]
- KeyPgOpNew → fxm [Added example of nested New [] to get a 2-dimentional object array]
fxm
Moderator
Posts: 12141
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: NEW operator

Post by fxm »

'New []' documentation page wrote: The total memory, in bytes, to be allocated with 'New datatype[count]' expression is calculated as 'sizeof(datatype) * count', plus 'sizeof(uinteger)' if there is an implicit or explicit Destructor. The total memory requested in bytes to be allocated must not overflow the value that can be held by a 'UInteger'. The extra uinteger, if allocated, stores the number of elements as part of the allocation, so that 'Delete []' Statement can determine the count of destructors to call.
To clarify the operation of 'New []' under the hood, an emulation of 'New []' with 'Allocate', being compatible with the call of 'Delete []' at the end:

Code: Select all

Type UDT
  Dim As Integer N
  Declare Constructor (Byval I As Integer = 0)
  Declare Destructor ()
End Type

Constructor UDT (Byval I As Integer = 0)
  Print "Constructor"
  This.N = I
End Constructor

Destructor UDT ()
  Print "Destructor"
End Destructor

Dim As Integer N = 3

'---------- Version with 'Allocate' using, compatible with 'Delete []' at end ----------

'there is destructor:
  Dim As Uinteger Ptr p10 = Allocate(Len(Uinteger) + N * Len(UDT))
  p10[0] = N
  Dim As UDT Ptr p1 = Cptr(UDT Ptr, p10 + 1)
'or if there was no destructor:
  'Dim As UDT Ptr p1 = Allocate(N * Len(UDT))
For I As Integer = 0 To N - 1
  'there is constructor:
    p1[I].Constructor(I + 1)
  'or if there was no constructor:
    'p1[I] = Type(I + 1)
Next I
Print p1
For I As Integer = 0 To N - 1
  Print p1[I].N,
Next I
Print
Delete [] p1
Print

'---------- Version with 'New []' / 'Delete []' ----------

Dim As UDT Ptr p2 = New UDT[N]
Print p2
For I As Integer = 0 To N - 1
  p2[I].N = I + 1
Next I
For I As Integer = 0 To N - 1
  Print p2[I].N,
Next I
Print
Delete [] p2
Print

Sleep
Output:

Code: Select all

Constructor
Constructor
Constructor
1776584
 1             2             3
Destructor
Destructor
Destructor

Constructor
Constructor
Constructor
1776584
 1             2             3
Destructor
Destructor
Destructor
Note: As the addresses of the 2 dynamically allocated objects are identical, it proves that the first object allocated using 'Allocate' has well been deallocated by 'Delete []'.
fxm
Moderator
Posts: 12141
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: NEW operator

Post by fxm »

KeyPgOpNew → fxm [Added of test if null pointer return, in 1st example]
Because: from fbc 1.06.0, 'New' returns a null pointer if memory allocation failed. This another important change is not explicit in changelog.txt ;-(
Post Reply