[Autogenerated] the problem we've seen right now is not just about writing,
it's also about reading if I try to read this cell where we know
there's nothing there but completely nothing,
there's no committed memory here,
we're going to hit an exception again which will again by
default will simply crush the process and so I want to make
these things work correctly.
So let's start with the right case with the right case.
What we need to do here is to protect against that using this exception
and then fix that memory fix in the sense to commit it if we indeed end
up in a cell that doesn't exist and is not really committed and in fact
we've seen already how to do that.
Let's do that here.
Even though we've seen the same same example conceptually in the
previous module so I'm going to call fixed memory here will get
exception code so I want to make it more robust and also the
address that we need to fix,
that's the address P in fact we won't have a need for any kind of message box
here because we're going to fix that and make that commitment.
So fixed memory, let's write it.
I'm going to go to the header file here so we need to call the
function whatever we want that's fixed memory.
The first parameter is the exception code and second one is the address to
fix so I'm going to press control dots to add Visual Studio let
Visual Studio provide me with a quick implementation here.
So let's start with the code if this is not exception access
violation and we have no idea what to do,
I'm going to return the exception continue search here.
However, if it is an access violation we know how to fix it.
We just need to call future look again and then provide the address whatever
that address is and that's the one that we get as a parameter,
which is very important.
We have to provide the address otherwise we'll have
something happening in a different region.
Want to specifically commit that particular cell so we have the cell size
here but of course it's always going to be rounded up to the entire page
really because you can't really commit or do anything that is not at least
the size of a page you want to commit here,
this is where using commit alone is the correct thing to do and
we're going to keep the memory here as read,
write and we can return exception,
continue execution to tell the CPU please try again.
So let's try it out.
If I go ahead and press control at five again,
let's start by using VM app again to see what is happening here.
Want to select the mini excel process again,
go back here and make the initial reservation.
Once I do that we can see the 256 megabyte address range being reserved for us.
So if I go ahead and perform a write operation now it succeeds.
It doesn't cause cause an exception and not just that
if you refresh the address space, notice notice what happens,
we now have a whole of four kilobytes in size that is committed and now
all the other parts of this range are still reserved so it kind of
punched a hole of committed memory in this case,
it was at the beginning of this chunk of memory because X and y are zero.
Now look what happens if I try to go to X equals one Y equals zero and
read that we don't get any error because remember when we committed we
committed an entire page that's four kilobytes.
And since a single cells just 156 kilobytes.
Sorry,
bytes then we actually committed 16 page up front so X equals one would work.
Then goes with two and so on.
Just simply just zeros deal.
So we don't see any kind of text but doesn't cause an exception.
If we go to X.
S 16 we expect that to cause an exception.
If you go back to read in X zero and y zero we'll get back our data.
If you select something else like 34 here and maybe 100 here,
get some _____ text here that will reflect the cell number and
click right If I go back here and refresh again,
you notice that now we have another chunk here somewhere
where we have our committed memory,
that's the address here and you'll notice that it's the same address shown
here in in the cell or at least something very close to it.
In fact,
it's not exactly that number because it's going to be
rounded down to the beginning of the page.
It's not exactly the same number, but it is in this particular chunk.
So we punched another committed hole here in this other otherwise reserved
region that you can see surround that committed page.
And this is the stuff that we actually pay for.
We pay for committed memory.
We don't pay for reserved memory.
This is why this mechanism is so efficient only when we need to
access some cell we're going to actually committed.
Otherwise we're not going to touch it and reserving the
memory initially was a very cheap operation,
which doesn't require almost anything.
So we can continue with these ideas for as long as we like,
we can have another right here.
We can go back to see what we have here cells that are adjacent,
supposed to still be working, but we'll see nothing.
If you go to a different location where we don't have that kind of protection.
Let's go here for example and do a re operation currently are
read implementation doesn't provide any kind of protection so
we're crashing our process.
So of course to actually make this robust.
We should do something similar in the read request,
but perhaps in this case simply show an error instead of actually
committing anything because if you haven't written anything reading
probably should just fail gracefully.
So if you go here to R reed case, let's see where that is.
So we have the read here.
We're just reading instead of just reading.
We should have a try except here as well here or here.
It doesn't really matter because that's the thing that's going to break here.
If we try to write something into non existing memory,
we can say execute handler.
And then this is in fact a good place to provide a message box saying,
well this thing is actually not committed.
So accessing non committed memory,
that's for the title and the icon error to make it clear this is an error.
Um and that's essentially it.
We can return zero here.
There's really nothing to put their perhaps even write
that kind of error into the text box.
I leave that up to you.
In fact doing that is going to be just fine in the way that it is.
So if we go ahead and allocate,
if I now read for something that of course hasn't been committed just yet,
I'm going to get that error which will not crush the process,
but just say that I'm accessing memory which is just not there.
Now,
the last thing I wanted to mention in this example here
is how do we free that reserved chunk?
The entire chunk.
So one thing you might want to do if we go back to our initial allocation,
maybe someone press the allocated button again.
So if m address here has a non zero value, then perhaps we should.
In fact, the first thing we should do is called the mutual free function.
With mutual free.
We can either de commit stuff or the release the memory entirely.
So there's nothing there.
In this case, I would like to release everything and to provide the address,
the size has to be zero and then then meme release is the actual
correct value to use to actually free that entire thing.
We should also do that probably when the dog boxes being closed,
that application is about to shut down.
It's not typically um it's not very important in this example
because the process is shutting down and the colonel will free all
private memory in the process regardless.
But still, it's a good thing to do that.
So technically,
if we go to uh the cancel or the cancel is really where you close the dialog box
or you can either even catch the uh the w destroy message.
Doesn't really matter.
But the correct way of doing that is again putting this kind
of code here when we close the dialog box.
That's the way to do that.
If you're you want to just de commit some chunk,
bring it back to the reserve state,
then you can use a mem de commit here while providing the
correct address and the correct size,
which is always going to be rounded up to the next page boundary,
in terms of address and in terms of size.