Pointers

The only way to access the same memory with different variable is by using pointers. In example below, we create a pointer, and when we want to dereference it to modify the content of the address that the pointer is pointing to, we use *ptrname or .pointer_value(ptrname).

@var aContainer: str[] = "hi there";                             //allocating memory on the heap for IMMUTABLE variable
var contPoint: ptr[str[]] = aContainer;

echo(*contPoint);                                                // here we dereference it and echo "hi there"

Bare in mind, that the pointer (so, the address itself) can’t be changes, unless the variable itself and pointer created are marked as var[mut].

@var[mut] aContainer: str[] = "hi there";                        //allocating memory on the heap for MUTABLE variable
var[mut] contPoint: ptr[str[]] = aContainer;

*contPoint = "hello sailor"                                      // we dereference it and modify because is mutable
echo(*contPoint);                                                // here we dereference it again and echo "hello sailor"

To see tha address of a pointer we use &ptrname or .address_of(ptrname)

Unique pointer

Ponters are very simimilar to RUST move pointer, it actually, deletes the first pointer and references the new one to the location of deleted one. However this works only when the pointer is unique (all pointers by default all unique). This is like borrowing, but does not invalidate the source variable:

var aContainer: arr[int, 5] = { zero, one, two, three, four };

var contPoint1: ptr[] = aContainer;
var contPoint2: ptr[] = aContainer;                              // this throws an error, cos, we already have another pointer to that variable

Shred pointer

Ponter can be shared too. They can get referenced by another pointer, and they don’t get destroyed until the last reference’s scope is finished. This is exacly like smart shared_ptr in C++. Pointer to this pointer makes a reference not a copy as unique pointers. Dereferencing is a bit complicated here, as when you dereference a pointer pointer you get a pointer, so you need to dereference it too to get the value.

var aContainer: arr[int, 5] = { zero, one, two, three, four };

var contPoint1: ptr[shared] = aContainer;
var contPoint2: ptr[shared] = aContainer;                        // this works, as the pointers are shared

However, the risk is that, when changing one pointer, the other one is now aware of chages, and mught have unforeseen consequences.

Raw pointer

Lastly, pointers can be raw too. This is the base of ALL POINTERS AND VARIABLES. Pointers of this type need to MANUALLY GET DELETED.

var aContainer: arr[int, 5] = { zero, one, two, three, four };

var contPoint1: ptr[raw] = aContainer;
var contPoint2: ptr[raw] = aContainer;

Deleting:

!(contPoint1)
!(contPoint2)

Pointer of a pointer

Pointer of a pointer then is just, as layer, after layer.

@var aContainer: arr[int, 5] = { zero, one, two, three, four };

var contPoint: ptr[] = aContainer;
var pointerPoint: ptr[] = &contPoint;

Dereferencing (step-by-step):

var apointerValue = *pointerPoint
var lastpointerValue = *apointerValue

Dereferencing (all-in-one):

var lastpointer = *(*pointerPoint)

Raw pointer of pointers are not suggested. If a pointer gets deleted before the new pointer that points at it, we get can get memory corruptions:

var aContainer: arr[int, 5] = { zero, one, two, three, four };

var contPoint: ptr[raw] = aContainer;
var pointerPoint: ptr[raw] = &contPoint;

Deleting:

!(pointerPoint)
!(contPoint)