 get started. So yeah, let's jump right back out, semantics, and we're talking about memory allocation, because we want to know what kind of errors can occur in memory allocation. So we talked about, just to briefly go over Monday, what types of, so what's global memory allocation? What does that mean? Sorry. Allocation that's done once, and not deallocated. Right, so allocation is done once, so memory is allocated right when the program runs, and then it's never released. So what's an example of this? Global variables, right? Yeah, classic example. All right. What about stack allocation? What's stack allocation? Yeah, memory that's allocated on the stack, it is directly in the name. But how does that differ from global allocation? Memory. What was that? It deallocates at the end of its usage. Yeah, so it's memory that's automatically created when that memory is in scope, right? So if you think local function variables and function calls, and then once that memory is out of scope, right, that memory is then automatically deallocated. So the awesome thing is you, the programmer, don't have to do anything to free this memory. What about the heap? A heap of allocation? Yeah, so heap is where we come in, right? So global allocation, the compiler controls, stack allocation, also the compiler controls, right? The heap allocation is us as programmers explicitly saying, hey, give me some memory operating system, I need some new memory. And as we all know from watching Spider-Man, right? With great power, it becomes great responsibility, right? So you, they're giving you the power to allocate the memory and you have to make sure you manually deallocate that memory. All right, so let's look at an example. So here we have, I would say, a normal complicated program. This is on the level of something that I would expect you to be able to understand on an exam. So this x here at the top, so what kind of memory allocation is that? Global. Yeah. All right. And so what about in here? So when we're executing the function main, this x, which x is this referred to? Global, right? I guess the answer could say it depends if we're talking about dynamic scoping or static scoping. But we'll say that this is a C program, so what, so C uses static scoping rules. So we know that that x statically refers to this declaration of an int x. And then when we get into here, so what type of allocation is going to happen here for this variable x? Stack, right? The program is going to create, so here's a little trick question. What's the size of that variable x? Is it going to be 1, 2, 3, 4, 5, 6, 7, 8 bytes for the string text thing? I did include it, I think, right? Oh yeah. Test is 4, hang is 3, plus 1 for the null byte. So is it going to reserve 8 bytes on the stack for this variable? What was that? Say it again? It's on the stack. What's the size? How big of memory is it going to... Wait. Just 1 byte? We have wide range of answers. 1 byte, 8 bytes. So how big is a character? 1 byte. How big are addresses on a 32-bit system? 32 bits, so how many bytes? 4 bytes. So what's the type of this variable x? It's an address, right? It's a character pointer. So what's inside? So if you draw the circle box diagram here, what's the value that's inside this variable x? An address. And how big is an address? 4 bytes. So you know that this string is only going to be 4 bytes on the stack, right? And the address that's in that string is going to be 8 contiguous bytes that contain testing followed by a 0. Where does the testing go? What type of memory allocation is that? I said it's like global, but I'm not sure if it is. Yeah. So actually the compiler can kind of do it however it wants, but this is actually global memory. And I think we did this last the week before spring break. We actually saw that this is actually in read-only memory, so we can't actually write... If we tried to alter this string x, we won't be able to change those parameters because that memory region is not writable. But that really doesn't matter. What matters is that the compiler sees, oh, there's this constant string. I need to globally allocate some space for that. And I'm going to put the address here where that is in x. Just like the compiler knows exactly where x, that inch x is located, it does the same thing for that memory address of that constant string. So then we get here, we're going to print out this x. So that x is in the heap. This x. Or is that... The character pointer x? It's calling from global. So this variable x, which is a character pointer, so what type of memory allocation is this? You said global. Well, it's in the heap because it's in the scope. Is it both? So the heap is only if we explicitly allocate it. So do we explicitly allocate anything here? No. So that's only if we call malloc in a C program. Or nu. Or nu in a C++ program. So then what type of memory allocation is just this variable x? That was stack. Stack. Right. x is located on the stack. The value that x points to is located in global memory. So any kind of constant string that's sitting around that always gets allocated in the global memory? Yeah. Exactly. Yeah, which is how you can get into it. Well, you can get into weird problems because it may, if you reuse that constant string testing somewhere else, it may put that in one place and put that same memory location there. Is that when we string the replicers or other kinds of data? That wouldn't happen with the 1337 and 10. The 1337? Yeah, these are, I mean it could happen if it needed to, but those are immediate values it can just put right in. Yeah, because it's not in a dress. It's not a character pointer. If you wanted to get a pointer to the value 1337, you'd have to do something else. Right. All right. So then what happens when we leave this scope? What happens to our lovely x? Yeah, it gets automatically deallocated. So x no longer exists after that point. Okay, so then we go into the function bafu and we see this character c. So what type of allocation is this? Global stack. Oh wait, no stack. Stack. Yeah. And so what's the size of this c? One byte. Yeah, exactly. One byte. Right? So that's the big thing is pointers are always the size of the address, address space on your system. So on 32 bit systems are going to be 4 bytes, 64 bit systems going to be 8 bytes. So that c would be looking in a similar fashion to the constant numbers? Exactly. Yeah, when you look at the assembly, it's going to create space on the stack and then it's going to just say move that whatever that c, yeah the ASCII value of c is move that into that location. All right, and then when we get past here, what happens to c? It's deallocated. It goes away. No more problems. Awesome. So what about here? So now we have a new x. So what's the size of this x? 32 bits, 4 bytes, right? This x. And so what type of allocation is happening here? Trick question. There's two types of allocations. Deallocated. Say it again? Say what? The int star x is stacked but the other side of it is even. Exactly. So the int star x, this x is located on the stack, stack allocated. And so there's going to be a box and the circle in that box is going to be the value of the return of calling malloc to get a new int. So there'll be a new box. Malloc creates a new box of whatever size we pass in and the address of whatever that new box in is going to be in the value of int star x. So there's two allocations here. So we have the heap allocation with the malloc and the regular stack allocation with variable x. Cool. All right. It's being greedy over there. Who? It's being greedy. It's taking up a lot more. Who's being greedy? That line of code isn't it? It's taking up a lot more than everything. That depends on how you use it, right? All right. So what happens when we get here? Deallocated. Yeah. So remember, so the int star x is on the stack so it automatically gets deallocated when we leave the scope. But the malloc, right, that memory remains. We never called three on that. So this memory is always going to be there and so we'll look at kind of what errs. So you've probably, well, I don't know, unless you're a perfect programmer, which I guess I can safely say, I'm not. I'll say that. I can safely say I'm not. I won't cast this version on any of your abilities. So when we do this, right, when we've allocated some new memory and then we leave like this, what happens to that memory that x was pointing to? Yeah, it just sits there. Comes garbage data. Yeah, so we now have garbage memory, right? So there's two main types of memory errs that we want to learn about. It's not garbage. You're just not using it. It's garbage. We'll talk about it in a second. Oh, because you're out of the scope. Because you're out of the scope. Not exactly. We'll see that in a second. Exactly, yes. We have no way to refer to that memory. Exactly. Alright, so let's do some box circle diagrams. I think we're... It's like when you delete something on your hard drive, but then you can't hold it right. Similar, yes. Alright, let's look at an example of one thing. So let's say I have a function, very functions, and inside this function foo, I can do it very similar, right, to what I had before. So int star x, let's do this, int x is equal to 100. I'll turn the address to x. Later I have somewhere else I have int star y is equal to foo. Is that a star? This is a star. That's a star. And what's the other thing? The ampersand signs. Yeah, this isn't quite... We know what it means. That's the important part. Okay, so let's just look at the function foo in isolation. So what is it doing? It's returning the address. It's returning the address of what? Does 100 have an address? What type of value is it at 100? It's an r value. Yeah, exactly. So let's look at this, right? We have x, right? Circle box diagrams, we have x. What's going to be after the first line executes? What's the value that's going to be in x? 100. And so what's the address of x? We call it alpha for now, right? So what does return address of x return? Alpha. Yeah, so is that valid? Can we do that? Yeah, we can do it, right? So it's going to return alpha. But then what happens here, once this program starts to stop, once this function completes and returns, what's going to happen to our memory here? We lost a link to that. Right, x is automatically delegated, which means this box goes away, right? Everything goes away. And so the address still exists, but it doesn't have a box associated with it, right? So now here when we say int star y is equal to foo, so I have now y. So what's the value that's going to be inside y? Alpha. What happens if I do, I don't know, what does star y do? D reference is y, but what box is that going to return? What do you don't know? Could it return 100? Yeah, right? So we don't, the memory associated with location alpha has been deallocated, right? So now there's, actually the compiler's kind of free to do whatever it wants at this point. It's undefined behavior. But it is very bad and can open up some of these security problems. And so we say that here y, so y here is a dangling reference, right? So it has a reference to some memory that no longer exists. So it has just access to that address. It has an address, so it has a reference to some address, but that address has no box associated with it, right? So any kind of memory can be in there. Any kind of data can be in there. Yes, exactly. There can be whatever in alpha. Swapping? That data that can be there. Actually anything. The point is we just don't know. We don't know what's in there. Because that location that was associated with alpha was deallocated here, right? And so it automatically went away. So let's consider a different scenario. That's heat, right? This? Where's this allocated? Stack. So let's say we have some function and we want to, we say int star x is equal to malloc, and I'm kind of going easy on this and not doing all the casting. We'll say for int star y is equal to, so we can say star x is equal to, somebody have a favorite number? One. Why do you want a favorite number? One favorite number, right? Favorite number regular. All right. So let me say int star y is equal to x, right? And what happens if later on we free, so self-check, could you, could you do a circle? There we go. It's like I thought I had more space. Okay, cool. So we have this main method. So, hey, self-check. Can you do the circle box diagram here? Yes, we're all awesome. Okay, let's take this first one. So how many variable names do we have? Two. Two, x and y, right? So we have x and x is going to be bound to some location, right? And so what's malloc going to do? Create some new box somewhere. Right, on the heap, exactly. And the value inside, there's nothing. So we'll give it the memory address, let's say alpha. So then what does this assignment statement do? We're saying x is now pointing at that box that we have just created. Correct. What does it do to my box circle diagram? Alpha. It assigns alpha to x. So it copies the address of malloc into the value of the location associated with x. So it's the location associated with x. We take alpha, we copy it into here. So after that, it's in here. So that effectively, x star will point to this, or star x will point to this box. Okay. So now when we do this line, when we say star x is equal to 20, what's going to happen? Alpha box now contains the value 20. Awesome. So then we say int star y is equal to x. Right, so this declaration means we're going to have a new location for y. So what's the value that's going to be in here? So we're saying y contains the value at y is the address of x. The address of x? Because it's a pointer. Is it taking the address of x and putting alpha in there? So what does the assignment say? So what do we do with the right-hand side? Whatever x is holding on to, which is alpha and assign it to y. So take the value in the location associated with x, copy it into the value of the location associated with y. So the value in the location associated with x with alpha, we put it into y. So what happens when we free x? What happens? We lose. No, we don't. Do we lose the pointer? Do we get rid of x? No. You know, we de-allocate the associated. Say it again. The memory associated with the address of x. It's dangerous. Yeah, so free x, right? But we've used x, right? We allocated some memory on the heap, and now we have to free that memory, right? That's our burden as programmers, yeah. Okay, if after the star x equals 20, we had y equals x, what would that do? Which one here? Wait, don't we have that? Instar y equals x? If it was just y equals x, not instar y. Oh, if it was declared up here? We just need to have a declaration, right? If it was just int y equals x. Ah, I see. That would be a type error. It would be a type error, but let's say we casted it or whatever. What's the difference here? It's certainly the other way. Is there any difference? So what does this assignment say then say? Distort the value of x. It wouldn't be able to be an extension of x. Take whatever is in action. Take the value in the location. Take the value in the location associated with x. What's the value in the location associated with x? Alpha. Copy it into the value of the location associated with y. Okay, so it's just here. So all pointers are, it will type abstraction. Because y is not a pointer. It would, you need to cast it. But you could do it. You could tell C that you want to do it because you're super smart. If you wanted to dereference it. Yeah, you'd have to cast y to an instar to be able to dereference it. But all that casting is, the computer only sees locations and data. So your cast just tells the compiler, hey, trust me, I know what I'm doing. I know I told you this was an int, but really it's an instar now. And then later on, oh, I know it's an instar, but really trust me, it's just an int. So it'll do it. Whether it works or not is on you. Yes. Yeah, but on the hood it's the same. So that's what this is exactly what it's going to look like. So then what are these? So you know the semantics of malloc, right? Malloc create a new box, give it a new address. So free, the semantics of free are exactly the opposite. So what is free going to do? Destroy the box. Destroy the box, which box? X's box? No. Which box? Alpha. Alpha. Yeah, so this is going to completely destroy this box. Then we lose the 20. Does it do anything to X? Not so you need the scope. That's where it's dangerous. No, exactly. It does not do anything with X. And now, so if I said star Y is equal to 100. So now is a question. Does it zero out X? I'm not sure. I don't think so. So let's look at this. So is Y a dangling reference? Yeah. Star Y equals to 100. It's assigning 100 in the address. So what was a dangling reference here? Why was Y here a dangling reference? Because it had an address that has no box associated with it. Yes, the same problem. Exactly, exactly the same problem. So here both, actually, well, we wouldn't call X a dangling reference because we've already freed it. So I believe it's probably going to zero this out or something. These would be more than that. Still semantic errors, though. Yeah. So when you free the memory, the address, you just can't use it. I mean, it's still like a number, right? Exactly. It is a number, but the point is that semantically that number doesn't refer to anything meaningfully in your program. So you don't have to set it equal to the pointer equal to zero or null when you're actually freeing it. I thought it was like typical practice or something. Yeah. Let me look at why that is. This is why we have manuals. Because I can't remember if it, because you're passing it into this function, so it can't actually change the value in that pointer. So maybe that's why you zero it out. You do zero it out for safety because you don't want to reuse it. Oh, yeah. So it must not be good. Interesting. So it's good practice, too, when you get out of age and also set whatever the point. Yes. To null. Yeah. So actually, that's a good point. So let's do this. Let's say that now X is equal to null. Right? It's a weird null. Right? So in here, so after these two lines execute, what's the value that's going to be inside X? Null. Null. But why is it still a dangling reference? Because it has the memory address in it of a box that no longer exists. Right? And here's where you can get into trouble. If, let's say, but you are assigning the value to that dangling address. That's possible. Just like, OK. So now if we say int star a is equal to malloc 4. So in our diagram, what's going to happen here? So we have an int. So we have a. Right? A is stack allocated here. And then we have the malloc. So malloc is going to create some new memory location. Right? Let's say it's up here. So what's the address of this? Beta. Say beta? Cool. Then we copy beta into here. So then if I say, let's see, star a is equal to 11. Right? So star a equals 11. So we're going to look at beta. We're going to look at betas here. And we're going to put 11 in here. And so then I say star y is equal to 11. And then let's say I print out star a. So what's a going to print out here? So a is this going to crash? Well, yeah. Could it crash? Yeah. Really crash? Yeah. Should it crash? Should it crash? And then what's this going to output? What would we want it to output? 11. 11. Right? That's what we want it to output. But what if alpha and beta are the same value? Because the system like malloc is creating data right on the heap and freeing that data. So it's reusing addresses. So if alpha and beta are the same value, then what's the star y equals 100 going to do? Put 100 here. And then when we output star a, it's going to output 100. So this is actually what happens most of the time because malloc reuses addresses very frequently. So when you call free and then you call malloc, you're going to get a pointer to the same address. And this is why this is conceptually, semantically it's a huge problem because alpha has no location associated with it, right? Does new have the same name? Yes. Under the hood, new definitely calls malloc. It does other stuff. It has to create the virtual function table so it can call all the functions of your objects and all that stuff. So there's like more work that's involved. But I think at the very bottom it calls malloc. I don't think there's a big, I don't think there's any difference between the two. Okay. So in both cases, these are dangling references. And they're actually one of the more subtle problems because your code could work like this. Oftentimes it will not crash when you dereference y because y is why it once held a valid address. So it's highly likely that that address, at least the computer, is a valid address. It's not like you're trying to dereference 0 or null, which is usually never allocated to your program. So this is why this is such a tricky error. So this is a dangling reference. So this is when you have a reference to a memory address that was originally allocated but is now deallocated. So you have a pointer with a value inside that pointer of an address that does not have a corresponding location. So what is garbage? Is it what we throw in the oceans and the trash? Technically. And computing. So what do we talk about as garbage? Not deterministic. In what sense? We talk like you're saying later that if you have a memory address that you cannot have a reference to, and there's no way to access that memory so that becomes garbage in the sense that you can never use it. Right. So in order to free memory, so global allocation is done by the compiler. It's never deallocated so we never have to worry about it. It's not like we're going to have too much global memory. Either a program works at the beginning with that amount of global memory or it doesn't. And stack allocation, we don't really have control over in some sense. The compiler is automatically allocating that memory and deallocating it automatically for us so we don't have to think about it. We have to keep memory. We call malloc or we call new. We're telling the system, hey, I want some new memory and I want to control when that goes away. So as we saw in this last example, how do we free memory? It's kind of a freebie. Sort of a deallocate. How do we deallocate memory? With the free function. But what do we pass into the free function? A pointer. And then the address that we want to free. That's how the system knows how to free that memory location. Like specify what address you want to allocate that. Is that an option in C? Or do you never get the option to specify the memory address itself? You could pass it in. Pass in the address. You can hard code. You can put in an explicit address into a pointer and dereference it. But the problem is it's not going to be allocated your program. It's going to have other system calls to tell the operating system to allocate that segment to your program. I think you could do it. Actually you could probably do it with your ELF file. Because the ELF file specifies the memory segments. You specify that you want a certain segment at a certain location and it will take care of doing that. So I think yes, but I would never, ever do that. But the kernel has to do that sometimes. Because the kernel has to play games with... Because the kernel is always in usually high memory locations. So anyways, a whole big thing. But yeah, once you talk about kernels, so you have kernels running and you have virtual memory, it gets kind of crazy. Cool. All right. Okay, so garbage, right? So free needs an address, right? But what if we can never get to that address? So let's say I have a program and I'm going to... So I have a function. This will just be that other example, right? So I have some function. It doesn't need to be void function, right? It doesn't take anything in. It has some end pointers. X and we're malloc-ing. Let's do something big. Okay, malloc a bunch of bytes. Let me return. Right? So this is pretty much all of our program, right? When we get into function foo, where's int start x going to be allocated on stack? Yeah, so it's going to be an x. It's going to have some box. So what's malloc going to do? Yeah, create us some 100 megs of memory, right? So it's going to create that on the heap. So this would be like a really big circle. And let's say it has some memory address alpha, right? So the way we have to free this memory location is we have to pass into the free function and we have to pass into alpha. This is the only way the system knows, hey, this is the memory that we want to free. We can't free the bytes. The 100,000 are the main... Yeah, we can't just say free this because we're malloc-ing stuff all over the place, right? So it internally keeps track of what chunks are what and how big they are and all this stuff. So x, so after this... After this, what's going to happen here? This may take a while. So malloc is going to create this. It's going to have some address alpha and then alpha is going to be put into the value of the location associated with x. So now any place in function foo, how do we free this memory address? Yeah, we call free x, right? Because x has this new memory location. So once foo executes, what happens to x? Yeah, stack allocated, right? So as soon as it's outside of the scope, x is going to be deallocated. So then how do I free this? We can't. We have no references to this location alpha, right? Because alpha varies at runtime. It's going to be different every time. We can't harden code that. Can you write that to null? Write what to null? What's the address of alpha? Alpha is an address. And it has memory in it that we've allocated on a heap. In order to free that, we have to pass free alpha. We have to pass alpha to the free function. But there's no way we can get to that value alpha, right? We have no references to this value alpha. So this is why alpha at this point is considered garbage because we've allocated it and there's absolutely no way our program can ever free that memory after this point, right? If we had other things where we had, like, y which had beta in it and then z which had alpha in it and so z, the address of z was beta and y is, I don't know, I'm running out of letters. C. So y, right? The pointer of y is z. Or even if this isn't z, we don't actually care if that is or is not named. Let's say it's not named. So here, b may be also on the heap. It may be also heap allocated, or beta, sorry, maybe also heap allocated. But through y, we can take the name y, we can dereference it to get beta, the location associated with beta, and then that, if we take that dereference, that now gives us this location. So here, even though we don't have a named variable with the value alpha, we can still, through our pointer dereferences, get to that so we could possibly free it if we wanted to. Or in the previous circumstance, there's no possible way we could free the location of the alpha. So I would like for our language with garbage collection to do this. Yeah, so what language is garbage collection do is periodically, so they keep track of all the boxes, essentially, and then they will start with some root, so they'll start with the variable names, so they'll keep track of the variable names. They'll start with those boxes, they'll follow all of these pointers, and then every pointer that they can see that is being used and is not garbage, and that other set of memory that it allocated but it did not find, that's garbage and it can be freed, and it can be reused. There's all kinds of techniques to make this faster, but this is exactly what garbage collection is looking for. Because garbage collection knows, okay, I know I have all these boxes, then starting from the variables, find all the boxes that I can find, and then anything I can't find is garbage. Okay, so here, in the main function, we have a pointer, and so we have an int star dang or dangling is probably how I should have said that. So, we're calling the function foo, right, and so foo calls in here to x, so x is stack allocated here, like we saw, and so x is going to have the value 100, and then we're going to return whatever that address of that stack allocated variable x is, and if it returns, dang is still going to have a value, and so we can print out dang as a pointer, so we can print out the actual address, that value inside this variable, and then we can dereference it and print that out too. And the value inside of it, right? But what is dang pointing to at this point? What was that? The return value of foo. What is the return value of foo? The address of x, right? The dangling reference at this point, right? It's in the name, right? So, it's a dangling reference, right? So, because whatever x is, as soon as foo returns, x is deallocated, right? It essentially no longer exists to our program, but we still have a reference to some memory location that has no semantic meaning at this point. So, we'll see what happens when we print this out, and then we'll call bar. So, bar has an int y, 10,000, a variable z1, 0, and then it's going to print out y and z, right? So, these are going to refer to these values here. It should print out 10,000 space 0. Then it's going to return, and then we're going to print out dang again, right? So, in a normal way, what should it be printing out here? It's actually going to print it out before. Yeah, it should be the same, right? I mean, looking at this, looking at bar, you can see bar isn't changing any global variables or anything, right? And dang itself is not global, right? So, here we have two identical lines, and then we have a function in between that doesn't change any global state. So, it should output the exact same thing, right? Yeah. What are the problems here to be the frankly called bar, so then in a way, so it wouldn't I mean, it should not, but you mean dang itself? Yes, because you call bar, right? Yes, I call bar. Technically, it should not, like you said, it should print out what it printed out before, but because you call bar, right? Now, it's looking at the memory that y and z help call right now. Okay, we'll look at that in a second. Yeah, yeah, yeah. But an important note, right, just so that it's clear, if this was like an x, right, calling bar shouldn't affect x unless we pass x into that function, right? That's right. Yeah, so looking at this, right, these two should print out the same thing, so we'll look at what it does and why it does that. Once it's got a dangling address, then you probably won't. I mean, yeah, you can probably use some, what is it, Bayesian reasoning, right, and say, well, I probably would be showing you an example if it was like that. Okay, so, what's going to happen when I compile this? Will this program compile? Are there going to be any errors? No. Let's see. So it's not going to be an error, but it is going to give me a warning. So the GCC compiler that we're all using on CentOS, so this is on CentOS, it's telling me that it's returning an address of a local variable, right? So why is that bad? Yeah, it automatically goes away, right? The scope, that address of X is only valid within that scope of that local variable. Yeah. So we'll bar the same memory allocations stacked out of our left foo head, and therefore tomorrow I'll have the same sort of variables that will be assigned to the foo. Let's find out. Does that way I have a thousand warnings on my code? Possibly. I mean, hopefully not this error, because otherwise really bad things will happen. Okay, so running this so it's going to first print out dang, so it's, I think it's on the 64-bit system, yes, which is why that address is so large, right? Is that right? Alright. So it's going to print out some address, right? The address of dang, and it's going to print out 100, right? Which is actually kind of what we expect, right? So after calling foo we see, oh great, we have a pointer to something, and then the value inside that pointer is 100. That's exactly what our code wants to do, right? We're pointing to some value there. And then it prints out 10,000 and zero. Oh, because bar, yeah. It's like that doesn't make any sense. 10,000 is not an address. Got it, yes. We'll get to you all. Alright, so the value inside dang does not change. It's still allocated inside it's, dang is still stack allocated inside bane scope, right? So the value inside there doesn't change. So this should not be surprising, right? That that memory address does not change. But, instead of what's at that memory address is now zero instead of 100. Super weird. So let's look at it again on, this is on my GCC, sorry, my Mac. So let's see. So it does give a warning as well with actually a nicer error message. Then when we run it, it says okay, the same thing, not the same address but an address in 100 it says 10,000 is zero and then it has the same thing with 10,000. So what's in that memory location is 10,000. What's 10,000? Why? So what we'll actually see So it's doing different stuff on different operating? Yes. So a, that's one thing, right? So we have a dangling reference. We have a reference to memory that's not allocated. That does not say what happens when you dereference that, right? That's why I undefined behavior. So by doing this it could be literally anything. But specifically what's happening is the stack is getting reused and so when foo executes right, it gets created when so main has an entry on the stack foo has an entry on the stack and then when foo returns that is automatically deallocated and then when bar is called the same stack that was once the memory locations of foo and that's why in this case I don't know a hundred percent if this zero comes from this zero of z. I should have changed it or if it's another zero some kind of padding. But this 10,000 is exactly from this variable y. So, yes so this is why, so you can see but the code didn't crash, right? It's easy to tell that there's a problem here but it doesn't, it just kind of works but it works in weird ways. Yeah, you don't, it's not set to define how it should work. Exactly, so, alright. So this is taking the references, we'll finish off all the semantics on Wednesday no, today's Wednesday, Friday.