Arrays & Dynamic Memory Address | Godot GDScript Tutorial | Ep 10.1

Godot Tutorials
26 Apr 202012:31

Summary

TLDRThis episode of the GT Script Fundamentals tutorial explores arrays in memory, explaining how they are stored in contiguous locations. It clarifies that in Godot, arrays are objects with reference counts. The tutorial demonstrates how assigning arrays to new variables shares the same memory reference, leading to changes in one affecting the other. It also delves into 2D arrays, showing how they reference memory addresses for sub-arrays. The script concludes with an explanation of shallow and deep copies, highlighting the importance of copying mechanisms to maintain variable isolation and independence in memory.

Takeaways

  • 📚 Arrays in Godot are objects stored in memory, with their own reference count and memory address.
  • 🔍 When an array is assigned to another variable, both variables reference the same memory location, meaning changes to one affect the other.
  • 🔑 Understanding memory address is crucial when working with arrays in Godot, as it impacts how data is manipulated and stored.
  • 💡 The script introduces shorthand notations to simplify the explanation of memory behavior without focusing on individual value addresses.
  • 👉 Assignment of arrays to new variables does not create a new copy by default; it shares the same memory reference, leading to shared state.
  • 📈 The concept of reference count is fundamental; it increases when a new variable references the same array object.
  • 🎯 The script differentiates between shallow and deep copying of arrays. Shallow copies only duplicate the top-level array, while deep copies duplicate all elements, including nested arrays.
  • 🌐 2D arrays are arrays of arrays, or sub-arrays, which also follow the same memory referencing rules as simple arrays.
  • 🔄 When performing a shallow copy, sub-arrays still reference the original memory location, leading to shared sub-array data between the original and copied arrays.
  • 📝 Deep copying is essential for creating completely independent arrays where changes to one do not affect the other, including nested arrays.
  • 🚀 The tutorial emphasizes the importance of understanding array behavior in memory for effective data manipulation and isolation in Godot scripting.

Q & A

  • What are arrays in memory according to the script?

    -Arrays in memory are a collection of items stored at contiguous memory locations. They are objects stored in memory and can be manipulated and used in various ways.

  • What is the basic concept of an array in Godot engine?

    -In Godot, arrays are objects stored in memory. A basic single dimension array is a variable assigned with literal values.

  • What does the script mean by 'reference count' in the context of arrays?

    -The 'reference count' refers to the number of variables that are pointing to the same array object in memory. When a variable is assigned to another, the reference count increases.

  • How does the script describe the memory representation of an empty array variable?

    -An empty array variable points to a specific area in memory with a type (in this case, array) and a reference count, which is initially one because only one item is pointing to it.

  • What happens to the reference count when a new variable is assigned to an existing array?

    -When a new variable is assigned to an existing array, the reference count of the array object in memory increases by one because there is now another variable pointing to it.

  • Why does the script focus on the memory address location of the array rather than the values?

    -The script focuses on the memory address location of the array to emphasize how arrays behave in memory and how they are manipulated, without getting into the details of the individual values' memory addresses.

  • What is the difference between assigning an array to another variable and using the 'duplicate' function?

    -Assigning an array to another variable creates a reference where both variables point to the same memory location, while using the 'duplicate' function creates a new copy of the array with its own separate memory location.

  • How does the script explain the behavior of 2D arrays in memory?

    -The script explains that 2D arrays are arrays inside an array, or sub-arrays. When a 2D array is assigned to a new variable, both the main array and the sub-arrays reference the same memory address unless a 'deep copy' is performed.

  • What is the purpose of the 'shallow copy' in the context of arrays?

    -A 'shallow copy' of an array creates a new array with the same top-level elements but with references to the same sub-arrays, meaning changes to the sub-arrays in the original array will affect the copied array.

  • What does a 'deep copy' achieve in terms of array memory management?

    -A 'deep copy' creates a completely independent copy of an array, including all sub-arrays, with new memory addresses. Changes to the sub-arrays in the copied array do not affect the original array.

  • Why is the 'deep copy' method important when you want to avoid affecting the original array?

    -The 'deep copy' method is important because it ensures that the copied array and its sub-arrays have their own separate memory locations, thus changes made to the copied array do not impact the original array.

Outlines

00:00

📚 Understanding Arrays in Memory

This paragraph introduces the concept of arrays in Godot's memory management system. Arrays are objects stored in contiguous memory locations, and the script explores how they are represented in memory. It explains the reference count mechanism, which increases when multiple variables point to the same array object. The paragraph also clarifies that arrays in Godot are simple objects and not just primitive data types. It emphasizes the importance of understanding memory address behavior when working with arrays, especially when assigning arrays to new variables, which results in both variables referencing the same memory location.

05:02

🔍 Deep Dive into 2D Arrays and Memory References

The second paragraph delves into the intricacies of 2D arrays, which are essentially arrays containing sub-arrays. It illustrates how memory addresses work with 2D arrays, showing that sub-arrays are references to other memory locations. The paragraph explains the implications of assigning a 2D array to a new variable, which results in both variables sharing the same memory references, thus affecting each other when values are changed. It also introduces the 'duplicate' function, which can perform either a shallow or deep copy of an array, with the former only copying the top-level array and the latter creating entirely new memory references for all elements, including sub-arrays.

10:04

💡 The Significance of Shallow and Deep Copies

The final paragraph focuses on the practical applications of shallow and deep copying in Godot's script. It provides examples of how shallow copying duplicates the top-level array but maintains the original memory references for sub-arrays, leading to shared changes between the original and copied arrays. In contrast, deep copying creates entirely new memory addresses for all elements, including nested sub-arrays, ensuring that changes to the copied array do not affect the original. The paragraph concludes with a demonstration of how to use the 'duplicate' method with a boolean parameter to specify the type of copy, emphasizing the importance of choosing the correct method to maintain data integrity and isolation between variables.

Mindmap

Keywords

💡Arrays

Arrays are a fundamental data structure used in programming to store multiple items in a single variable. In the context of the video, arrays in Godot's scripting language are objects stored in memory. The script explains how arrays behave in memory, with a focus on their memory address and reference count, which is crucial for understanding how changes to one array can affect another if they reference the same memory location.

💡Memory Address

The memory address refers to the location in a computer's memory where a particular item, such as an array, is stored. The video script discusses how arrays in Godot have memory addresses and how variables point to these addresses. Understanding memory addresses is key to grasping how arrays are manipulated and how changes to one array can impact another if they share the same address.

💡Reference Count

The reference count is a mechanism used to keep track of how many variables are pointing to the same object in memory. In the script, it is explained that when a variable is assigned an array, the reference count is set to one. When another variable is assigned the same array, the reference count increases, indicating that multiple variables are referencing the same array object in memory.

💡Shallow Copy

A shallow copy of an array creates a new array object in memory but does not duplicate the objects that the original array references. The script uses the term to explain that when a shallow copy is made, the new array shares the same sub-arrays as the original, meaning changes to the sub-arrays will be reflected in both the original and the copied array.

💡Deep Copy

A deep copy, in contrast to a shallow copy, creates a completely independent copy of an array and all the objects it references. The video script explains that a deep copy is made using the 'duplicate' function with the boolean value 'true', resulting in a new array that has its own separate memory address and does not affect the original array even if its sub-arrays are modified.

💡Sub-arrays

Sub-arrays, also known as nested arrays, are arrays that are elements of another array. The script discusses how in Godot, when a sub-array is created, it is essentially a reference to another memory location. This is important because it affects how changes to the sub-array are reflected in the parent array.

💡Variable Assignment

Variable assignment is the process of associating a value with a variable name. In the context of the video, when an array is assigned to a new variable, it is explained that the new variable points to the same memory address as the original, unless a copy (shallow or deep) is made, which creates a new memory address for the copy.

💡Indexing

Indexing refers to the method of accessing elements in an array using their position or index. The script uses indexing to demonstrate how values are accessed within arrays and sub-arrays, and how changes at a specific index can affect the array's behavior.

💡Memory Behavior

Memory behavior pertains to how data structures interact with memory and how they are managed by the system. The video script delves into the memory behavior of arrays in Godot, explaining how arrays are stored, referenced, and manipulated in memory, which is central to understanding the video's theme.

💡Isolation

Isolation in the context of the video refers to the concept of having variables that are independent of each other. The script explains that the purpose of variables is often to provide isolation, where changes to one variable do not affect others. This is particularly relevant when discussing the difference between shallow and deep copies of arrays.

Highlights

Introduction to the episode focusing on arrays and memory address in Godot.

Explanation of arrays as collections of items stored at contiguous memory locations.

Description of arrays as objects stored in memory in Godot.

Introduction to single-dimension arrays and their behavior in memory.

Clarification that variables point to areas in memory and have reference counts.

Demonstration of how assigning one array variable to another affects memory reference counts.

Illustration of how changing values in arrays affects reference counts and memory locations.

Overview of how arrays and their values are represented in memory addresses.

Explanation of assigning an array to a new variable and its effect on memory addresses.

Detailed look at how memory behaves with a 2D array in Godot.

Discussion of sub-arrays and their reference locations in memory.

Introduction to shallow copies and deep copies of arrays in Godot.

Explanation of the duplicate function and its options for shallow and deep copies.

Example of a shallow copy and its impact on memory references and sub-arrays.

Example of a deep copy and its impact on memory references and sub-arrays.

Conclusion emphasizing the importance of understanding memory addresses in array manipulation.

Transcripts

play00:01

hello and welcome to another episode in

play00:03

the GT script fundamental tutorial

play00:05

series in this episode we'll be taking a

play00:08

look at arrays in memory address arrays

play00:11

are a collection of items stored at

play00:13

contiguous memory locations we know how

play00:16

to manipulate and use arrays but let's

play00:18

go ahead and take a look at how arrays

play00:20

behave in memory so in Godot arrays are

play00:24

objects that are stored in memory the

play00:27

key thing to keep in mind is that arrays

play00:29

are just objects now this is a basic

play00:32

single dimension array as you can see

play00:35

here we've declared a variable and we've

play00:37

assigned it an array I like to call

play00:39

these simple arrays because they're just

play00:41

literal values before we begin I need to

play00:43

go over some shortcuts I'm going to be

play00:45

doing in this slideshow this is because

play00:48

I just want to focus on the memory

play00:49

address location over the whole picture

play00:52

but to preface when you create an empty

play00:54

variable what you're really doing is

play00:57

you're taking that variable and you're

play00:58

pointing it to an area and memory

play01:01

address and this is what it would look

play01:03

like you would have a type in this case

play01:04

array and you would have a reference

play01:06

count and it's one because one item is

play01:09

pointing to it now let's say you do

play01:10

variable another array is equal to empty

play01:14

array well you're really pointing to

play01:15

this object so it's reference count goes

play01:18

up to two that's basically the basics of

play01:21

how it looks like in memory now another

play01:24

shortcut I'm gonna do in this video is

play01:25

the following I'm just going to put an

play01:27

integer inside a block to represent how

play01:30

it behaves in memory but in reality what

play01:32

we're really doing is when we do have an

play01:35

index we're actually just pointing to

play01:37

another object in memory that of course

play01:39

keeps count of its reference or

play01:41

reference count so when we go ahead and

play01:43

add so when we go ahead and add a value

play01:45

in this case 1 what we're really doing

play01:47

is we're pointing to that same object in

play01:49

memory and we're increasing the

play01:50

reference count by 1 and of course when

play01:52

we go ahead and change that value we're

play01:55

just pointing to a different object in

play01:56

memory and changing its value adding a

play01:59

reference count of 1 and decreasing the

play02:01

reference count of the other now this

play02:03

episode we only really care about the

play02:06

reference count or rather the location

play02:08

and address memory of the array rather

play02:10

than the address memory of the values so

play02:13

that's all I want to do is

play02:15

just preface but we're not gonna pay any

play02:17

attention to this all we care about is

play02:19

when I do short hands it's really

play02:21

representing this but even when I do

play02:23

shorthand our main focus for this

play02:25

episode is just the memory address

play02:28

location of the array and not the memory

play02:31

address locations of the values this is

play02:33

what a simple array or rather our my

play02:37

array variable would look like in memory

play02:39

as you can see here we have our variable

play02:42

my array and it's actually pointing to

play02:44

somewhere in our memory address keep in

play02:48

mind this is a basic simplification of

play02:51

how arrays behave in memory but

play02:53

nonetheless this is how it would

play02:54

normally behave variable points to a

play02:56

location memory address we have our

play02:59

indexes 0 1 2 and we have our values 1 2

play03:03

3 keep in mind that location memory

play03:05

address starts at the beginning of your

play03:08

array now let's go ahead and take a look

play03:10

at what happens when we try to assign

play03:12

that variable my array into a different

play03:15

variable in this case our new variable

play03:18

copy array will be assigned the values

play03:21

from my array when we print this out

play03:24

into console using the print statement

play03:26

it will return 1 2 & 3

play03:28

same thing for copy array 1 2 & 3 but

play03:30

when you assign an array to another

play03:32

variable how does that look like in

play03:34

memory well as you can see here we have

play03:36

a variable copy array and it actually

play03:39

references the same array in memory

play03:41

location as the my array the specific

play03:46

reasons for this can get really deep and

play03:48

it is considered its own topic however

play03:50

to keep things simple just remember when

play03:53

you do direct manipulations such as copy

play03:56

array equals my array keep in mind we're

play03:58

not using a duplicate function what

play04:01

you're really doing is you're saying

play04:02

wherever my variable my array is

play04:05

referencing in this case location 100

play04:08

assigned that reference location to the

play04:11

variable copier what this means is that

play04:13

if we were to change a value let's say

play04:16

the value at index 0 which is 1 if we

play04:19

were to change 1 into 100 what will

play04:22

happen is that copy array and my array

play04:24

will have their indexes changed to a

play04:27

hundred because they're both pointing

play04:28

to the same memory address location so

play04:31

to take a look at that we have our

play04:33

assignment like in our previous slide my

play04:35

array at index 0 is equal to a hundred

play04:38

again notice how we're using my array

play04:41

and we're assigning it a hundred and

play04:43

notice how when we're printing copy

play04:45

array a different variable name it will

play04:47

also change its value to a hundred even

play04:50

though my array and copy array both

play04:52

started with the values one two and

play04:54

three again this is because copy array

play04:56

and my array both point to the same

play04:59

reference in address memory and so

play05:02

changing the value of one will actually

play05:04

change the value of the other now let's

play05:07

go ahead and take a look at how memory

play05:09

behaves with a 2d array and all 2d array

play05:12

is is an array inside an array which can

play05:14

also be referred to as a sub array so

play05:16

our variable 2d array has the value 0

play05:19

and then a sub array with the values 1

play05:22

and 2 when we create our variable 2d

play05:24

array and assign it a value what we do

play05:26

is we reference a location in memory

play05:29

address and as you can see here our

play05:31

index at 0 has the value 0 but notice

play05:33

how our value at index 1 is this

play05:37

reference in memory address that's

play05:39

because this is how arrays behave in

play05:42

memory for GT script when we create a

play05:44

sub array what we're really doing is

play05:46

we're calling a reference to another

play05:49

location and address memory and then

play05:51

from there we continue our values in

play05:54

this case index 0 is 1 and index 1 is 2

play05:57

so you can see how this works if we want

play05:59

to call our sub array we call 2d array

play06:02

index 1 and then index 0 for the value 1

play06:06

or index 1 for the value of 2 now if we

play06:08

take this 2d array and we assign it to a

play06:12

new variable in this case we're calling

play06:14

our new variable copy 2d this is what it

play06:17

looks like what we're doing is we're

play06:18

taking the reference to location address

play06:22

memory we're assigning that location to

play06:25

our copy today's so they both point to

play06:28

not only the first section of the array

play06:31

but also the sub array so if I were to

play06:34

change a value here instead of 1 we turn

play06:37

this into a hundred what happens is when

play06:39

we do a print statement to either copy

play06:42

to

play06:42

and even 2d array it's gonna show zero

play06:45

new value and then - because we're

play06:47

referencing the same location address

play06:49

memory for both variables now this is

play06:52

where the duplicate function comes into

play06:54

play many times when you create a

play06:56

variable you do not want to share the

play06:59

values between two different variables

play07:01

the whole point of variables in most

play07:03

cases is basically isolation isolation

play07:06

meaning when you change one variable you

play07:08

should not be affecting other variables

play07:10

so the duplicate function comes with two

play07:12

choices you can do a shadow copy or you

play07:15

can do a deep copy now if you do a

play07:17

shallow copy and keep in mind that

play07:18

shallow copies only makes a copy of the

play07:21

surface of your array this means that

play07:23

all sub arrays will still point to a

play07:25

reference in memory basically the same

play07:27

reference that your copied array is

play07:29

pointing to now a deep copy will make a

play07:32

copy of everything including sub arrays

play07:34

so let's go ahead and take a look at

play07:36

what that would look like in address

play07:38

memory here's an example of shallow copy

play07:40

we have a variable with a basic array

play07:42

and then we use the arrays built-in

play07:44

method called duplicate and we pass in

play07:46

the value of false by passing the

play07:48

boolean value false we are telling this

play07:50

method to make a shallow copy of our

play07:53

basic array and then pass that in to

play07:55

copy array when you use a shallow copy

play07:57

what you're saying to the system the

play07:59

compiler is that you want to take just a

play08:02

shallow copy of the array and put it

play08:05

into a different location in memory

play08:07

address my array has an array at

play08:09

location memory address 100 by doing a

play08:12

shallow copy you say variable copy array

play08:15

take the values from this location and

play08:17

then put that in a different memory

play08:19

address location we can point to instead

play08:22

so as you can see here we have our

play08:24

location at 200 now if we change the

play08:27

values of my array we will not affect

play08:29

copy array and if we change a value and

play08:31

copy array we will not affect my array

play08:34

let's go ahead and take a look at what a

play08:36

shallow copy looks like when you're

play08:37

dealing with sub arrays so as you notice

play08:39

here we have a sub array one two sub

play08:42

array with three four and we're also

play08:44

passing the false value letting the

play08:46

compiler know that we want to do a

play08:48

shallow copy of my array and pass that

play08:50

into copy array so we have my array one

play08:53

two three four and it creates it sub

play08:55

in location memory address 100 the

play08:58

values in index 0 and 1 are 1 & 2 and

play09:01

just as we would expect our value in

play09:03

index 2 is just a reference to another

play09:05

address memory location where we

play09:07

continue the sub array index 0 3 & index

play09:10

1 4 so when we duplicate a rather when

play09:13

we when we do a shallow copy notice

play09:16

we're using the false value and our

play09:17

duplicate function when we do a shallow

play09:19

copy and we pass it into a new variable

play09:22

this is what it looks like so when we do

play09:24

a shallow copy notice how we copy

play09:26

everything in the first layer we we take

play09:28

everything and we basically duplicate it

play09:30

we create another location in 300 and

play09:33

notice how we have 1 & 2 separated from

play09:35

location 100 when we change indexes 0 n

play09:38

1 in my array we do not affect copy

play09:41

arrays values and vice versa however we

play09:43

also copied my arrays reference to

play09:47

memory address location for its sub

play09:49

array so as you can see here our sub

play09:51

arrays are both pointing to location 200

play09:54

and if you were to change a value in

play09:56

this sub array it will affect how my

play09:59

array works and it affects how copy

play10:01

array works so just keep that in mind

play10:03

you are copying everything including the

play10:06

reference to location and address memory

play10:08

now let's go ahead and do a deep copy so

play10:10

we have the same values in my array but

play10:13

this time instead of passing the fossil

play10:15

in we're passing the true value in to

play10:17

our duplicate method and by doing this

play10:19

we're telling the compiler to do a

play10:22

basically deep copy take all the values

play10:25

take all the sub arrays and give them

play10:27

their own separate memory address

play10:29

location so again when we create my

play10:32

array we're creating it in memory

play10:34

address location and we're creating a

play10:36

sub array in a different memory address

play10:38

location let's go ahead and take a look

play10:40

at a deep copy and how it looks like in

play10:42

memory address so when we use the

play10:44

duplicate method and pass in a true

play10:46

boolean what we're telling the compiler

play10:47

is we want to do a deep copy to my array

play10:50

and then we want to pass that value in

play10:53

to copy array so what that does is we

play10:55

look at the memory address for my array

play10:57

and we say ok let's copy this and put it

play11:00

into memory address 300 but when you do

play11:03

the copy you also look at its references

play11:05

and then you go to the references and

play11:07

you say hey let's go ahead and take the

play11:09

sub-array and we'll add it to a new

play11:11

address in memory location where we will

play11:14

then pass a new reference to our copy

play11:18

array basically the array we want to do

play11:20

a deep copy for we pass the reference

play11:22

value or the new reference to memory

play11:24

address location to the new array so

play11:26

that's how we get the value 400 there's

play11:28

a lot going on but just know that at the

play11:31

end of the day this is what it looks

play11:33

like in memory address so now when we

play11:36

change the sub-array of copy array we

play11:38

will not affect my arrays sub array

play11:40

because the sub array in my array is

play11:42

pointing or rather referencing an

play11:45

address location that is not the address

play11:47

location our copy array is pointing to

play11:49

so in this case we're pointing to 200

play11:52

copy raised pointing to 400 when we do

play11:55

this copy we get the same exact values

play11:57

if we were to compare them for equality

play11:59

they would be equal but if we were to

play12:01

compare them to their memory address

play12:03

location they'll come back false because

play12:06

everything in the deep copy is pointing

play12:08

to a different address in memory

play12:10

location versus our original array well

play12:13

I hope you learned a lot today thank you

play12:15

to everyone who has subscribed to my

play12:16

channel and thank you for clicking the

play12:18

like button there is no github project

play12:20

for this episode so I hope to see you in

play12:22

the next episode have a wonderful day

Rate This

5.0 / 5 (0 votes)

Related Tags
Godot EngineGT ScriptArraysMemory ManagementData StructuresProgramming TutorialDeep CopyShallow CopyReference CountingGame Development