 So midterm tomorrow, right? So we're going to do our usual going-to-the-practice midterm. Do you have any questions? You know the drill? Stop me, raise your hand, all that kind of good stuff. Maybe we have a question before we start. Yes? I won't be here for the midterm tomorrow. Is that OK? No. OK, next question. Also probably not a question to ask. Don't you mean that the midterm is going to be Friday? Friday, yes. That's right. Sorry, good question. I just think in the classes in Monday when I say Friday, right? Think about you guys so much, you're just the next day to me. OK, any other questions? Yes? Sorry, I don't know if you're going to ask this. Are you going to be giving us first-of-all sets on the regular test also? Maybe, maybe not. That's it for now. You should be super familiar with how to do first-of-all sets, right? Oh, my coffee's very hot. OK, so problem one. Consider the grammar with the following first-and-follow sets, right? So here's our grammar. We have the first sets, S, B, C, and D, and we have the follow sets. OK, so the first question asks, prove that the grammar supports a predictive parser. So what are the rules that a grammar can support a predictive parser? Things you have to check if they're a first-sets. Yeah, so if we have some rule like A goes to alpha and another rule A goes to beta, where alpha and beta are a whole right-hand side of any number of symbols, then it must be the case that the first of alpha is not equal to the first, or has no intersection with it. The intersection of the first of alpha with the first of beta gives us the empty set. So what's the second rule? The rules first-and-follow must be disjoint. In what case? The first is epsilon. Yeah, so if there's epsilon, those are different, right? If epsilon is in the first of alpha, so if the right-hand side can go to epsilon, then it must be the case that the first and follow of the right-hand side are just disjoint. So first of alpha, intersect with follow of alpha is empty set, right? Or no, follow of A. So can you write this? Did I prove anything here? What did I do? I just wrote down rules, right? So if you did this on a test, I don't know. How many points did you expect to get? Maybe like a quarter? Maybe? I don't know. People did this. This is why I'm making this point, right? This is not a proof, right? You actually have to actually show, OK, in this example, how do these rules hold? For instance, just for space reasons, I'm going to do this, get rid of this. But we have our rules. So here we have b goes to cd, and b goes to little b, big d, little b, right? So it must be the case that the first of cd, right? So what's the first of cd? C and then d epsilon, yes, cd epsilon. And the first of, I'm just going to do capital F for this, little b, big d, little d. What's that? Little b. And we can see that the intersection of those is equal to the empty set, right? That's good. OK, we have this. And then I'm going to check d's too. So we're going to check the first of little c, big c, which is little c, little c. And then intersect that with the first of epsilon, epsilon, yes. Hopefully it should be a trick question. I think I have not epsilon here. All right, so the intersection of these two sets is the empty set. And finally, we have d, big d. The first of this is little d. Intersect that with the first of epsilon. And finally, which is the second tending epsilon. And then we get that that is the empty set. So this is showing that the first rule holds for this grammar, right? So this is where it tests. I'll probably write out all the firsts here, but in the order of time. So this shows that that first part works. So the second part is if we have a right-hand side that goes to epsilon, then it must be the case that the first of that right-hand side is not intersect with the follow of the left-hand side, right? That's what that rule says. So let's think about which of these can go to epsilon. So it can b, little e go to epsilon. What's this first set? Is it epsilon? In that example, the first one we did first of c, d. But it's c, d, and epsilon. Isn't it just c and epsilon? Because don't you only look at the first non-terminal, the c? You include the first set. Well, how do you calculate the first set of a serially with? I thought you just looked at the first non-terminal. Well, you do look at the first non-terminal, right? Look at the first symbol, right? You say, just like calculating any kind of first set, right? You say, take the first set of the left-most symbol, which is c epsilon. You subtract epsilon from it. You add it to the first set. And then you go to the next one because there's epsilon in it. So you add d minus e minus epsilon from that to add little d. And then you say, did I make it all the way through? Yes, I made it all the way through. So I have to add epsilon. You could think of it as, let's say we added some new rule e here for whatever reason, some new non-terminal. And we said e goes to c, d. And so the first of c, d is the same as the first of e. So you know how to calculate this. So you know how to calculate this. This is the exact same thing. So it's just like making a rule that exists only in one place for those two things. OK, so then going back to here. So applying that here. So then what's the first of this big b, little e? c, d, b, right? Subtract epsilon from it. And then I say, is there an epsilon in this symbol? Yes, go on to the next symbol. The next symbol is a little e. What's the first set of little e? E. Are there epsilon in all of these symbols? No. So there's no epsilon here. Is there an epsilon in the first of c, d? But I'm going to underline that. We have to worry about that. Is there an epsilon in this rule? So do you actually have to do that? I mean, that'll work right there. Can you just look at the right side and look at it? Yeah, is there an epsilon in the first set and go to the whole estimate? Because isn't that what we already did calculating in the first set? Yes, well, but you need to look at them because it's the whole right-hand side rule. For instance, just looking at this, if you looked at s goes to b, the little e, you'd say, oh, there's an epsilon here, so I have to worry about this. But this right-hand side is never going to go to epsilon. That's why I'm saying you look at the first of s and you'd see that there's no epsilon in the first of s. Yes, yes. So you do need that, but you need to know which rule it came from. Because that's what you want to find out. Is epsilon coming from this rule or this rule? So that's basically what I'm doing here. But yeah, you can narrow it down further by saying, like, OK, I'm only going to look at the left-hand side of b, c, and d because there's epsilon in here. And then I'm figuring out which rule to apply. So can this ever produce epsilon? C, little c? Oh, this? Yeah. Yeah, this? Oh, this? Yes. OK, so I need to show that the first of c, d, intersects with what? How do I apply that little follow of b? Yeah, so follow of b. So this needs to be equal to null for this to be true for the empty sets, all right? So the first of c, d, we can just try to get up here, is c, d, epsilon, intersect that with the follow of b. So we have the follow of b here, which is e. So is there any intersection in here? No. So that's the empty set, that's good. And we check here, we check, we're going to check the first of epsilon, union with, well, I'm going to write it out here to save space, the first of epsilon, which is the second to the epsilon. We're going to intersect that with the follow of what? Doing the second rule, c, follow of c. And this we know is going to work, right? Because there's not going to be any epsilon to follow sets. But we can do it mechanically, and we can look, and we can see that these sets. OK, the next rule, first of epsilon, just equal to the second to the epsilon, intersect that here. What is it? Follow of d, which is going to be, and this intersection is the empty set. But this, now, yeah. So this question is asking to prove that grammar supports a predictive parser. And then at homework, you're asking that the grammar needed a predictive parser, right? So I didn't know that you would go about it the same way. Yes. Really? Yes. Oh, OK. Yeah, this is how you show that the supports of predictive parser actually don't memorize all homework questions. Yeah, well, this is explaining why this grammar or prove that the grammar supports the two sides of the same coin. Any questions on that? Yeah. Can you explain again why you compare the first epsilon with the follow of d? Here. Yeah. So I'm applying. So these are the two different rules, right? So this first rule is all about saying that basically in English it says, if I have a given non-term on the left-hand side, I know always know which rule to choose by looking at the first character, right? So it says, deciding between these two rules, I can tell why I look at the first character, which rule it is. The next rule says, if a rule goes to epsilon, like cd, right? Both c and d can go to epsilon. So if that goes to nothing, then I need to distinguish between if it went to something versus the case where it went to nothing, so what came after me, right? So if cd went to epsilon, so if I read just one character, how do I know that character came from either c or d or came from whatever came after b because b went to epsilon? OK, so the first part only applies to the s and the second part applies to all the rules. No, no, this applies to everything. It's every single rule. Whatever you have a choice between rules. Yeah. So for the second rule, then couldn't you just look through all of the first sets and just see which of those have epsilon in them and just do the intersect operation with their respective follow sets? No, because you need to know the exact rule. You've already proven that the rules are disjoint, right? So here I know that cd is disjoint from big b, little d. But so I know there's not going to be epsilon in either of them. So you need to find out which specific rule is going to give you epsilon. Because it doesn't matter what this guy produces because we already know that this is always going to have a big d. And we can tell which one because of that. I was going to get the same answer either way, but on your slides and on the homework solution, it said first of a intersection follow of a. Yeah, I did need a specific one. And it's been a perfect one. OK, that makes more sense. Yeah. OK, like first of d here? Yeah. Yeah, OK, that makes more sense. OK. So then you still have to see which of the two rules? No, but in that case, you don't. Yeah, then that's a lot easier. OK, sorry, that was. Yeah, it's been working. Yeah, so if you think about it, it's going to be larger, right? So first of b is going to contain the first of cd, right? Yeah, OK, that's good. So it's going to have a b in here. That's good. First of c, yeah. So c is c epsilon, b is c epsilon. OK, yeah, this says that only one of the rules, possibly the same as epsilon. And this says, can I tell, yeah, if it's one of these, or the thing that came after me? OK, that makes sense. Good. Yes, this is how you should do it. OK, any more questions on this problem? All right. OK, write the parse b function of a predictive recursive descent parser for the grammar. Print out the rule after successfully parsing the rule, as in the homework. You can assume you have functions getToken, ungetToken, and syntax error. You can assume that you also have parse functions for all the non-terminals, all the other non-terminals, right? So the first thing we know, right, is we can know that we're going to parse b. Give us this, parse b. So the first thing we do is what? Yeah, we need to get a token, right? So I'm going to use t type. OK, then what do I check? Close that. Gans. Close to cb. First of cb, yeah. So I need to check which rule is this, right? So I need to say, is this token in first of cb, right? And I know first of cb is cd and epsilon, so I do. But can I check for epsilon? No, right? It's not going to give me, it's a token, right? Just write something from in, but it can't read nothing from in, but it's either going to give me a token or give me the end of file, right? So I'll say if t type is equal to c or t type is d, right? So I've just read these tokens. Then what do I definitely know about this? Should be d, right? Yeah, c and d. So in your homework? Yes. I like to see the solutions. I'm pretty sure you also have to add in the follow b. We'll guess that in a second. You could do it either way. Oh, you can. Yeah, I'd kind of like to do it as a separate clause so that it's clear. OK, so I thought about it. That's probably good, but I thought it was wrong. No, it's not wrong. I'd say you could do it both ways, right? I guess from an engineering perspective, it's better to do it all at once. That way, you don't repeat everything that's in here. So yeah, let's do that. OK, so why do we do that? Why do we check the follow of d here? Because the first of cd contains epsilon. Right, because the first of cd contains epsilon, right? So if this goes to epsilon, then we know it must be in the follow of b, right? So if it's not an e, then it's going to eventually be a syntax error, right? So let's do that. Or cd e. Then we can print out, right? This is the rule b goes to cd. Is that what I do? Am I done here? Just pull it up. Unget token and call part c and part e. Yeah. So we need to unget. So even actually, we're going to move this print up down farther because we actually don't know that we've successfully parsed of d goes to cd, right? We know we've chosen this rule. It should be this rule. But we have to parse the c and then parse the d to know that we successfully completed this rule, right? So we need to call an unget token to put the token back because we just peaked that token, right? So we have to put it back. And then we want to call parse c and then parse d, right? So once these two functions return, right? If there's a syntax error in either one of those, they'll call syntax error and parsing will terminate. So we know if they return, we've successfully parsed a c and then a d, which means that we've successfully parsed b goes to cd. Now we need to check. Right, it's not this big, right? We're not writing in front of everyone. OK, they have a rule. Other rule. So what's the first of b, big b, little b? b, just a little b, right? So else, oh, it's the Python else, sorry. Else if t type is equal to little b, then do I unget token? Why do I not unget token? Because it's a terminal. Right, it's a terminal, right? We consume that b, which is perfect. So I'm going to successfully consume that. So now we need to call what? Parse b, parse d, parse big d, right? We want to call parse d again, or not again, but we want to call parse d, right? That's going to go parse a d. And then what are we going to do? Do we say yes, we've done this correctly? Make sure it's another b in token. Yeah, I remember this was bdb, right? So we need to call getToken again to check, hey, the next token better be a b, otherwise we have problems. So we call tType people to getToken, and then we're going to call tType to getToken, and then we call parse b. So if, yeah, so if tType does not equal to a b, then what? So it's an index here. Yeah, I'm going to put that in there, right? Definitely syntax error, then close this up. So now we know we've parsed this completely. Now we print, because we know we've parsed this successfully. So we print out b goes to little b, big b, little b plus u. And then what if it's neither of these things? Syntax error, right? That's it, right? Questions on this? The homework actually had a main function. What? Oh, write a main function? No, you only have to do whatever it tells you to do, right? So here, all you have to do is the parse b function, yes. And we're not storing the b, the little b at all? Storing? Like, do we need to store it at all, or? Where are you going to store it? I don't know. Yeah, so I mean, that's, this is more of like kind of abstract parsing, in a sense, right? Yes, like in project four, when we do the parsing, we're actually building data structures that represent the parse tree. Here, we're not really doing that. We're just outputting which rules occurred, right? But you could easily, once you have this structure, you can easily add in. So here, I would create some structure that represented b, big b, little b. Is that the same thing for the last problem in the homework with the circle box diagrams? You've had all of them, but the question is, let me ask for p and q. Yes? What about q? Yeah, you'll be asked to, yeah. So I gave more in the solution there just to show what it looks like. But like, as we see on here, I think in here, I ask for almost everything. So yeah, you just have to read and understand what the question is asking you, right? All right, then we do the parse c function. Let's, let's see, is c interesting? I don't think c is any more interesting than b, actually think b is more interesting. So let's, let's leave it for now and then we'll come back to it if we have time. That way we can make sure we get through all the problems. Problem two, consider the following code in c syntax. Okay. So here we have a piece of c code and then we need to put the output of this program assuming that we use static scoping and the output of the program assuming we use dynamic scoping. So just when we're looking at this problem, what can you tell about these two answers? They should probably be different, right? I mean, so if you do something and they come out the same, you should probably double check, right? To see if something went wrong. I mean, that'd be a very tricky question if they did come out exactly the same, but for different reasons or something. But anyways, this is our test taking tips, right? You gotta meta think about the test. Okay. So let's do this statically, right? That should be pretty easy, we just put it in our compiler. All right, so we can easily, one way to do this is to just resolve the references. You can either do it beforehand or as you're simulating execution. I think beforehand is kind of easy, right? We can just map every instance statically to a declaration, right? So we know what everything refers to. So I know that refers to here, this refers to here. Where does this j refer to? This one? Yeah, over here, right? Then that j refers to global j. Also, if you're taking a test, right? Would I probably have you print out an uninitialized variable? Probably not, because what would you output, right? The compute. That's not correct, though, I'm curious. Does your computer print out undefined? Did you print out undefined variable? No. No, yeah. So I would probably not make you do that, right? So you want to think about what's, if you got to a point where you're printing out j and you're like, huh, j is nothing. It hasn't been assigned to. Probably doing something wrong. Okay, so let's go to this execution. So I'm going to put here the value. So I have only three declarations, right? So I'm going to put here the value of each of these. Bless you. Okay, j is equal to one. I already decided this j is this j up here, so I know inside here is going to be one, right? This has the value one. So I'm going to call pop. Pop is up here. And I'm going to say, is j less than four? Yes, j is less than four, so increment j. So what's the value of j now? Two, right, two. And then I'm going to print out j. So the first thing I'm going to print out is two. This pop returns, I return here, I call baz. Baz sets this j equal to zero. Then inside here, this j is set to five. And then we call pop again. Pop says, is j less than four? Yes, it's two, so we increment j, three. And then we're going to print out j, so we're going to print out three. We return from pop, which is here. Then we print out j, so which j is going to print out? Zero, yeah, I remember. All right, so that's a scope in question, right? All right, sorry. Okay. That's our five, then we call pop again. Pop is going to go in here, is j less than four? Three is less than four, so increment it. So print out four, a baz is going to return. We call pop one more time. Is four less than four? Oh, so we print out a lot. Questions on that? So now how does this change when we, in general, right? What's our strategy now that we're talking about dynamic scoping? What are we going to build as we do the execution? Yeah, the symbol table, right? We're going to manually build the symbol table as we're executing this function, this program. So here in the global scope, right? Our very first thing we're going to have is a variable named j, right? Has name j, no value, yeah. We get into main. Main doesn't have any local variables, so we're not going to create a new scope in our table for there. Then it's going to set j is equal to one. So this reference, how do we resolve this reference with dynamic scoping? How many? Exactly, we look up our table and we see the first thing we see that's defined with j, right? Oops, so we set one in here. Then we call pop. So pop goes, then it looks up j. Is this, so first you have to resolve the j, right? Is this j less than four? Yes, then we increment j. So this j is going to be two. Then we're going to print out j, so it's going to print out two. And then pop will return. Then we call baz. So inside baz we have a new local variable called j, right? So I'm going to draw this for kind of the new scope. Oops, that's a terrible one. And then I set this j equal to zero. Then I enter a new scope here, right? A new block that has another local variable called j. So I do the same thing, right? I just create a new scope called j. And I set this j to be five, right? So we're looking bottom up. So it's going to set this to be five. Then we're going to call pop. So then pop's going to say, which j is this going to test? The five, yeah, so it's five less than four? No, easy questions, right? So we print out five. So this pop returns. And then what happens when we leave this scope? What happens to our table when we leave this scope, right, go for it here? Yeah, this one leaves our scope, right? We can no longer reference that, it's gone. It leaves our simple table. Now when we print out j, this is going to look up, which j? Okay, it's going to print out zero. And then it's going to call pop. So it's zero less than four? Yes, so we increment it. So we print out what? Pop returns from here, pop returns from bad. So what happens when we leave this scope? Yes, right? That's the really important thing that we have to remember to do when we're doing dynamic scoping, right? We have to make sure when we leave scopes, right, these, the variables in that scope are automatically deallocated. So then we get back into main, we call pop, is two less than four? So we increment that, and we're going to print out three. Questions on that? So what should you double check while you're doing this? What are you most likely to mess up on here? Definitely not in dynamic scoping, but actually in general, you're, can be very easy to flip this around or mistake it, right? Or try to, I don't know, calculate it in your head and get it wrong or something, right? So, you know, take your time, double check, three less than four, right? So what's the answer to this one? Your bet's going? Isn't it fun? Look at all your pointers we have. It's a perfect, perfectly right amount of pointers. Okay, this is such a short program, too, right? All right, so we have local variables P, Q, W and X their memory locations, right? So even though these are technically the same symbol, it actually doesn't matter, right? Because we know addresses are different from variable names, right? Names are bound to locations. Locations have addresses, so we're just using symbolic variables here. Just like here when we use memory one and two. So we have Q is being mallocked. We have W is being mallocked and we set X equal to the character X. We set P equal to the address of Q. We then basically draw the box of diagrams at this point right here. And then we dereference P and set that equal to the address of W. And then we triple dereference P and set that equal to X. Then we set X equal to the character P and then we output the circle box diagrams again. So any question on what this program does? Okay, so let's get it wrong. You didn't know you'd draw so much in this class, did you? See, I don't want to do this. Just do it here, okay. So we have our local variables, right? We have any local variables we have? Four, right? So these are local variables, which means they're gonna be bound to their boxes, right? So we have a variable name, it's bound to a location. So then what do we know about the values in some of these? Yeah, right? So it's actually kind of, I don't know what the change is. Does this assume all uninitialized pointers are equal to null? So what's inside of X? We don't know, yeah, garbage, let's call it garbage for now. So we know when we start, I'm gonna use a capital N for null, because I didn't get myself a wide enough circle. And then X is something we don't know. So we've done all this, right? We've created all the boxes from there. So now we have this line. So we're calling malloc, so what do we know what malloc does? Creates a new box, this is a really big box. All right, what's the address of that box? I'm one. I'm one, right? Well, I guess we didn't draw it, but we should put, so the address of P is W, the address of Q is X, the address of W is Y, and the address of X is Z. So then what does this malloc do? So what does this malloc return? Address. An address, right? What's specific to what address? One in this case. Yeah, one in this case. And then so what are we doing with one? Yeah, we're copying that, it's an L value to an R value, right? L value equals R value. So we're taking that value, that R value, copying it into location associated with that L value, with the value in the location associated with that L value. So we're gonna copy one, and we're gonna put it inside Q. Then we're gonna have the next malloc, that's gonna be memory two, and so what's gonna happen after this malloc? Let me stir that. Yeah, two is gonna be in the location, value of the location that's bound to W, right? So we're gonna put that in here. And then we're gonna set X equal to the character X. Right, so this is again, L value is equal to R value. So we're gonna put this X here. And then we do P is equal to the address of Q. So what's the address of Q? X. X, right? It's just the address, it's an R value. So we're sending an L value to an R value, so we're gonna do what with X? With this address X? The location associated with P. Yeah, copy it into the value of the location associated with P, so this is gonna put X in here. So then I go back to the question, right? So I've drawn box circle diagrams for P, Q, W, and X. I also need to draw and label star P, star Q, and star W. So what's star P? It points to like this. Yes, the box. Right, so I did this, now I need to do star Q. So what does star Q point to? The box at memory address one. The box at memory address one, yeah, so. Right, did that one, and then star W? Same deal, but to memory address two. All right, since we're here, we're just gonna keep going. All right, so I'm gonna keep using this. Let's snap about this. This is point one, box circle diagrams. So let's keep going. So let me say star P is equal to the address of W. Right, so let's say address of W, Y, and so the address of W is an R value, right, of Y, and then star P is gonna return what? An L value and R value. L value, yeah, better be an L value because it's on the left-hand side of an assignment statement, right? So star P, so we already said star P points to what? Q, so then what am I doing here? So I'm gonna take Y, and where am I putting, copying Y? Where the one is? Where the one is, yeah, inside the circle, right? So take this R value Y, copy it in the location associated with star P. So star P points to this box right here, so I'm gonna copy Y and put it in that box, yes. Just a quick hypothetical question. If it was star P and ampersand, like is there a way to make it so you can change the address for the pointer? Like, where you would replace X? This? No. No, no, no, okay, no. The locations and the addresses associated with them are fixed, right, in memory. Yeah, this is why you can't do, so this is why address of operator returns an R value, right? So you can't say the address of P is equal to 10, right? Right. There's no way to do that. Okay, so we did this. Now we have to do star star star P equals X, so which is more difficult to think about. Thank you, star star star P, right? X is this, right? We know what X is. So we have an L, so we know that star returns an L value, right? So we know star star star P is gonna return an L value, so we have an L value is equal to L value, so we know how to handle that, right? We're gonna just take whatever's inside X, which is this character X, or we're gonna copy it somewhere, right? But the question is where do we copy it? So what's star P? The location associated with Q, yeah, it's this box, right? So this is star P, and then, so then we dereference this again. Yeah, the box associated with W that has the address Y, so it's this box. And then we dereference that. This one, right? So where we're gonna copy the character X, right here? Cool, then I say X is equal to the character P. Oh, yeah. You never do this, it points to nothing, right? And that's supposed to never do that. No. I mean, I'm not intentionally. Yeah, then we say X is equal to P. So what do we do with P? Copy it into the location associated with X, right? So this has us do this, P, Q, W, X, and all the dereferences. So X, the X inside P points to the location that is at address X, right? So this is star P, star Q is dereference Y, or point to the box that's at the location that's at address, the location that's at address Y. So we have here, star Q, and then here we have star W, question line. Let's make this harder. What are all of the aliases in this program? So what's an alias? Yeah, two or more names that have the same, any aliases are two or more names for things that have the same location, right? Starting from our variables, right? So P is associated with this location. Is there any other way to reference this location, P? No, there's no way, right? Starting from any of those other variables, there's no possible way to get there. What about Q, this box? Yeah, Q and star P, so how do you write aliases? Q and star P, right? Okay, this is one set of aliases. What about W here? So can you have all three? Just isn't it Q, star, star, P? Yeah, so W is a name for this, right? And we can go backwards, we can see that star Q is a name for this. What else? Star, star, P. Star, star, P, right? What about X? Are there any other aliases for X? No, they're working at one point though, right? Let that change because of the way the program executes. So then what about this location? Yeah, it's garbage, right? We actually have no way to reference this. So there's no, not even a single alias. I mean, not even a name for this one, right? Which is why it's garbage, we cannot reference it. What about this box? Yeah, so we can get there a star W, right? Star, star, Q, triple star. See, is that it? Yeah, I think that's, I mean, this is all the boxes, right? So, cool. This is even an easier question because I only had to do just two of these. Any other questions on this one? Do we have any other questions? Yes, okay, cool. Okay. Okay, consider the calling C, blah, consider the following code and C syntax and assume stack memory allocation for nested scopes. Nested scopes are used, is used. Recall that dangling reference is the reference to memory gesto is randomly allocated, but it's now deallocated. And garbage memory is memory that's been allocated on the heap but has not been explicitly deallocated, yet is not accessible by the program. So, here we have a code and it's asking us the memory locations that are garbage, memory locations at points one and two, dangling references at points one and two, and memory locations that are deallocated at location two. So, what should we use to do this? Box, our whole diagram. Box for X, that's weird if you don't capitalize the else. And then inside main, we have A, we have A and C, right, there's some C, and then finally inside this scope, we have B. So, this first one, we malloc, we're mallocating new memory, we're setting it equal to A. So, we're copying, so, we have a new memory location at address one with nothing in it yet and we're copying that one into A. So, A, now points to one. Then B, we are doing the same thing. So, we're creating a new memory location, calling it two, setting, copying two, the R value there into B. Now, we're setting C is equal to the address of B. So, what's the address of B? Address of B, right? We're gonna put that into C. Then we're going to allocate a new chunk of memory called memory three and we're gonna copy that into B. And then we're gonna set B equals A. What's that's gonna, what is that gonna do? A equals B, sorry. You're going off my words, not what I wrote. Yes, that's good. Copy three into A, right? So, it's gonna change this to three. C, X equals C. So, we're going to take the address of B and copy it into X. Then, we are taking the address of A and copying it into W. So, the address of A is here, copying that into W. Now, we're at location one. So, we can answer the questions at location one. So, the memory addresses that are garbage at location one. So, from here, maybe it'll help to draw the graph, right? From here, we can get to here with the D reference. The address of B means we can get here. Three means we can get all the way here. Address of A means that we can get here and the address of B means that we can get here, right? So, yeah, there's no way we can access one or two, right? So, one and two are garbage. Dangling references at location one. Are any of these pointers pointing to something that does not exist? So, what would you write here? None, because it told you in the question, you wouldn't ask, what do I write if none of them apply? I'm gonna tell you to look at the question. Okay, then we free B. So, what does freeing B do? Does it get rid of this box? No. All right, what does it do? What does it get rid of? Yeah, the value, it looks up the thing that B points to, right? So, it returns, it's gonna free, it's gonna look inside here, say, okay, what location has address three? So, it's this one, and it's gonna say, okay, I'm gonna deallocate this. We free B, and then what happens between there and here? We leave scope, whose scope? So, then what happens to the location associated with B? It goes away too, right? Automatically, because it's automatically deallocated. So, now we're at location two. So, which memory addresses are garbage at location two? Still one and two. Dangling references at location two? Yes, so C points to something that no longer exists, right? And what about A? A as well, right? It points to three. And what about X here? Yes. Yeah, so it'd be X, A, and C, right? If you draw the arrows, it's very clear, yeah. So, free of B got rid of the C validation and the stack allocation? No, free B got rid of memory address three. And then why would it get rid of? Because B is declared here in this scope, so it's automatically deallocated as we leave scope. What was it, X, A, and C? So, what about W? Is W a dangling reference? Star, star is dangling. Yeah, you could say star W is dangling, but W itself is not dangling, right? So, dangling reference means you can't be referencing so it points to nothing. Okay, what memory locations have been deallocated at location two? Three? And B, you can do the stack. And the address of B, right? Because of stack allocation, it's been automatically deallocated. So, B is wrong, you have to put address B. I think I'd probably count it, but I would put address of B to be more precise. So, you don't write W star. For four, you could do that. I would do a lot of that for you. That's not wrong. Can you explain why the dangling references are at all pointers? I just don't understand why it's like X, X star is the dangling reference, like X. Oh, because dangling reference means the address inside the pointer dangling, basically. The address inside there, so, let's go, maybe we go back to that. It's a reference to a memory address that was originally allocated, but is now deallocated, right? So, inside X, right, there is a memory address, but the problem is that memory address has been deallocated and no longer exists. Cool, any questions? I think you all are pretty ready for the good term on Friday, so. On Friday, not tomorrow. Don't get them on. You're already starting to say a question, so. All right, let's go ahead, okay. Okay, if you go down to, like, the end of the part, right there. Oh, go down again, sorry, to the other house. Oh, I didn't, I erased the, I didn't get the answer. Oh, you erased it, okay, never mind. I don't know. No, you're fine, you're fine. Yeah, basically, like, if it's not here, it's a syntax error. Oh, okay, you have, doesn't equal B. Yes. I was equal to B, so I thought they were reversed. All right. Or you could go not equal like this. Right, okay, cool. Yeah, right, because if it's successful, then we only care about the case where it's not, exactly. Then we're gonna continue successfully and just print everything out. Okay, cool, thanks. All right, questions? Yes, project questions. Okay. You're just having to put the point at all most. I have a question in the midterm, I'm not. So, for the first problem, you know how you say, if they have, if you have an option, you have to compare the options, right? Yes. What if there's three options? You just compare them all, and once you get to compare, one, like, you get to compare them all to each other. The intersection of all of them, I mean, they're, you know what I mean? Yes, you have to pair, I just compare them, you have to compare everyone. Oh, okay. So, if you had three rules, you would, then you need to be distinct. You need to be able to decide between them. So yeah, if you had like, if we had like, A goes to little A, and A goes to little B, and A goes to little C, and A goes to D, right? You have to make sure that these are all completely distinct. So you have to be A, B, A, C, A, D. Yes. BC, BC, BC, BC, BC. Yeah, because you can't do, if you try to inter, if you try to intersect, if I intersect two of them and I get something, I don't want to intersect that with something else. Right. Because I want the fact that there is an overlap there. Oh. Would you give us something like that? Possibly. Yeah. I mean, it's, it's the same as doing it three different times here, right? It was so little time to write this much information. So little time. Yeah, like on the first test, it was not enough time. I didn't check any more. You guys did really well, though. I know. But that was hard. We would have done better if we had more time. Yeah. I promise. Okay. I concur. All right, yeah, that was not my question. Okay. Any other midterm questions? Let's answer your number one. I just did it. I went over it. He means on the actual test. Please. I was not answering. Cool. Okay, you have project questions? Then I think I'm just going to answer them and not record it. I'll just add those to the end. All right.