Hello, and welcome back. In this lecture, I want to talk about dynamic memory allocation.
This is directly related to pointers, you can only employ this on
pointers. So let's get started.
So whenever you define a variable in c,
the compiler automatically allocates the correct amount of storage for you based on the data type.
We've seen this throughout. When we create integers, floats, doubles, we don't have to allocate any memory.
The compiler does it for you. It actually allocates some memory.
Same goes for pointers by the way. When you create a pointer, memory is allocated for you,
so that it stores a pointer type, an address.
Now that doesn't mean that memory is allocated for that address.
Up until this point, whenever we assign data to a -- to a pointer,
we've always assigned an existing variable.
So if we wanted to assign
data to a pointer, we've used the ampersand address of operator
on a variable that variable already had memory allocated for it.
But what if you wanted to create a pointer and you didn't want to assign it the address of operator,
you wanted to dynamically allocate memory. That's what this whole entire lecture is about.
So it's frequently desirable to be able to dynamically allocate storage
while a program is running. Allocate memory as you need it.
If you have a program that is designed to read in a set of data from a file
into an array in memory, you have three choices.
You can define the array to contain the maximum number of possible elements that compile time,
it's a fixed size.
If you define the array that has 50 elements,
it's only going to contain 50 elements. The compiler determines that it's 50,
it's going to allocate that much memory when it runs.
You can use a variable length array to the dimension the size of the array runtime.
We talked a little bit about these variable length arrays,
they're not supported until C11. They're actually taking out C11, they're adding C99.
This is where you can put in variables.
But these are still sort of fixed size because
all that means variable linked arrays all it means is you can pass in variables for sizes.
But they're still static.
Or the best choice is you can allocate the array dynamically as you need it.
And there's different c functions that you can call to do this.
So it's going to be very useful to be able to dynamically allocate memory.
So with the first approach which we've been doing all the way up until now
whether it's an array or whether it's a data type, it's a fixed size.
You have to define your array to contain the maximum number of elements
that will be right into an array.
So you would do something like this, int dataArray [1000].
What this means though is the data file cannot contain more than a thousand elements.
If it does, your program's going to break.
So you just have to hope that the whatever file you're reading in doesn't have a lot of data.
Your program will not work with large sets of files or large files.
And if you do want to work with large files you have to go back and you have to make the array larger.
You have to change the size,
but then you have to recompile it in on all that stuff, it's compiled time.
No matter what value you select, you always have the chance of running into the same
problem again in the future because it's a fixed size.
This size is determined when you compile the code,
it doesn't adjust when you run the program.
It doesn't dynamically change.
Using dynamic memory allocation functions, you can get storage as you need it.
This approach enables you to allocate memory as the program is executing.
So think of the advantages of this. First of all
you don't create a ton of memory that you might not use
you're only going to create as much as you need.
And if you do need more, you can allocate more.
You don't have to go back and recompile and change the size.
So dynamic memory allocation is the way to go.
It depends on the concept of a pointer
and it provides a strong incentive to use pointers in your code.
So we talked about the advantages of pointers
and you may have thought to yourself well, okay, they're a cool concept but why do we need to use them,
this is one of the big reasons,
so that you can allocate memory dynamically.
And again, what is this -- C is all about being efficient language
and not using a ton of memory.
So c runs on embedded systems, real-time programming
and this is one of the reasons why because you can limit how much memory you use
based on the need.
So dynamic memory allocation allows memory for storing data to be allocated dynamically
when the program executes.
Allocating memory dynamically is only possible
because you have pointers available.
Because you have an address and you can change
how much the pointer is pointing to, you can readjust the memory.
The majority of production programs will use dynamic memory allocation.
If you're writing code in c, you're going to use this.
Even if you're a beginner, you're going to use dynamic memory
allocation. Most useful programs will employ this concept.
Allocating data dynamically allows you to create pointers at runtime
that are just large enough to hold the amount of data you require for the task,
so you're not wasting memory. Vital.
We also have to talk about the heap versus the stack.
There are two ways that you can store memory in a program,
two different data structures you can store data on the stack or you can store
data on the heap.
Dynamic memory allocation reserves everything on the heap.
We're not going to go into detail of how these are organized but essentially.
When you store data on the heap it allows for
more change.
You can arbitrarily change the size of data objects
and it sticks around a lot longer when you allocate memory in a heap,
it sticks around the entirety of your program.
When you use a stack, it's more limiting.
The stack is used for everything from function arguments and local variables.
That's where everything those are stored.
And that's why we talked about the call stack.
It looked at methods and
functions. I use methods every now and then, but methods is really an object-oriented term,
so functions.
Everything related to functions are created on the stack.
So what that means is when you execute a function,
it gets put on the stack. The local variables get put on the stack.
When you exit the function, everything gets deleted.
So memory located on the stack does not stick around for very long.
That's one of the reasons when you dynamically allocate memory it's on the heap
because you control when you use it
and when you when you don't use it, you allocate it and you delete it.
Stuff on the stack, you don't control. It automatically gets deleted,
automatically gets allocated.
So local variables, variables inside functions like the main,
those are created on the stack and so forth.
The memory on the heap is different, it's controlled by you, the programmer.
When you allocate memory on the heap, it's up to you to keep track of when you the memory,
you have allocated is no longer required, so you have to delete the memory.
You have to free the space
when it's no longer used by you. And this is important because memory
is very, very a scarce resource.
Today we have a lot of memory that you can run a computer,
12 gigs, 16 gigs whatever it is. But
for programs that are embedded running on devices,
you don't have that much memory necessarily. And so you want to control
how much memory use and you also want to release the memory when you're done using it
so other applications can use it.
Again, more important in low-level embedded type systems.
But this is a freedom that many languages don't have.This ability to
control your manager memory by the programmer,
and it can make the program much more efficient and much faster.
So in the next lecture, we're going to talk about how you can actually do this,
what functionsyou can invoke. Obviously, there are different functions that you can call
to allocate memory into free memory up. Thank you.