Go to the Next or Previous section, the Detailed Contents, or the Amiga E Encyclopedia.


14.4.1 Object and simple typed allocation

The following sections of code are roughly equivalent and serve to show the function of NEW, and how it is closely related to NewR. (The type can be any object or simple type.)

  DEF p:PTR TO type
  NEW p

  DEF p:PTR TO type
  p:=NewR(SIZEOF type)

Notice that the use of NEW is not like a function call, as there are no parentheses around the parameter p. This is because NEW is an operator rather than a function. It works differently from a function, since it also needs to know the types of its arguments. This means that the declaration of p is very important, since it governs how much memory is allocated by NEW. The version using NewR explicitly gives the amount of memory to be allocated (using the SIZEOF operator), so in this case the declared type of p is not so important for correct allocation.

The next example shows how NEW can be used to initialise several pointers at once. The second section of code is roughly equivalent, but uses NewR. (Remember that the default type of a variable is LONG, which is actually PTR TO CHAR.)

  DEF p:PTR TO LONG, q:PTR TO myobj, r
  NEW p, q, r

  DEF p:PTR TO LONG, q:PTR TO myobj, r
  p:=NewR(SIZEOF LONG)
  q:=NewR(SIZEOF myobj)
  r:=NewR(SIZEOF CHAR)

These first two examples have shown the statement form of NEW. There is also an expression form, which has one parameter and returns the address of the newly allocated memory as well as initialising the argument pointer to this address.

  DEF p:PTR TO myobj, q:PTR TO myobj
  q:=NEW p

  DEF p:PTR TO myobj, q:PTR TO myobj
  q:=(p:=NewR(SIZEOF type))

This may not seem desperately useful, but it's also the way that NEW is used to allocate copies of lists and typed lists (see 14.4.3 List and typed list allocation).

To deallocate memory allocated using NEW you use the END statement with the pointers that you want to deallocate. To work properly, END requires that the type of each pointer matches the type used when it was allocated with NEW. Failure to do this will result in an incorrect amount of memory being deallocated, and this can cause many subtle problems in a program. You must also be careful not to deallocate the same memory twice, and to this end the pointers given to END are re-initialised to NIL after the memory they point to is deallocated (it is quite safe to use END with a pointer which is NIL). This does not catch all problems, however, since more than one pointer can point to the same piece of memory, as shown in the example below.

  DEF p:PTR TO LONG, q:PTR TO LONG
  q:=NEW p
  p[]:=-24
  q[]:=613
  END p
  /* p is now NIL, but q is now invalid but not NIL */

The first assignment initialises q to be the same as p (which is initialised by NEW). Both the next two assignments change the value pointed to by both p and q. The memory allocated to store this value is then deallocated, using END, and this also sets p to NIL. However, the address stored in q is not altered, and still points to the memory that has just been deallocated. This means that q now has a plausible, but invalid, pointer value. The only thing that can safely be done with q is re-initialise it. One of the worst things that could be done is to use it with END, which would deallocate the same memory again, and potentially crash your machine. So, in summary, don't deallocate the same pointer value more than once, and keep track of which variables point to the same memory as others.

Just as a use of NEW has a simple (but rough) equivalent using NewR, END has an equivalent using Dispose, as shown by the following sections of code.

  END p

  IF p
    Dispose(p)
    p:=NIL
  ENDIF

In fact, it's a tiny bit more complicated than that, since OOP objects are allocated and deallocated using NEW and END (see 17 Object Oriented E).


Go to the Next or Previous section, the Detailed Contents, or the Amiga E Encyclopedia.