Cairo has a few ways of storing an object in memory and getting a pointer to it (which can be used by other functions):
Memory segment allocation: The alloc() function can be used to create an arbitrary-length array.
Single item allocation: The new operator initializes a single item and returns a pointer to it.
Local variables: You can allocate a local variable and retrieve its address. See Accessing the values of the registers.
The standard library function
be used to “dynamically” allocate a new memory segment (see Segments).
This segment can be used to store an array or a single element.
from starkware.cairo.common.alloc import alloc func foo(): let (struct_array : MyStruct*) = alloc() # Set the first three elements. assert struct_array = MyStruct(a=1, b=2) assert struct_array = MyStruct(a=3, b=4) assert struct_array = MyStruct(a=5, b=6) return () end
The “new” operator¶
new operator takes an expression and pushes it onto the stack and returns a pointer to
memory address of that object. For example:
func foo(): tempvar ptr : MyStruct* = new MyStruct(a=1, b=2) assert ptr.a = 1 assert ptr.b = 2 return () end
Note that unlike
alloc(), which allocates a new memory segment, the
creates the object in the execution segment (see Segments). Since memory in Cairo is never
freed, both approaches have a similar outcome – you can use the pointer even after the function
On the other hand, this means that the
new operator can’t be used for an arbitrary-sized arrays.
new operator is useful since it allows you to allocate the memory and initialize the object
in one instruction. In fact, you can use multiple
new operators in the same line if necessary.
This is theoretically equivalent to the following code:
tempvar obj : MyStruct = MyStruct(a=1, b=2) tempvar ptr : MyStruct* = &obj
&obj is currently not supported for
tempvar, so this code does not compile.
You can use
new to allocate a fixed-size array using tuples:
func foo(): tempvar arr : felt* = new (1, 1, 2, 3, 5) assert arr = 5 return () end
For arrays of structs you’ll need to explicitly cast the pointer:
func foo(): tempvar arr : MyStruct* = cast( new (MyStruct(a=1, b=2), MyStruct(a=3, b=4)), MyStruct*) assert arr.a = 3 return () end