 Morning, everyone. Sorry to have a little mic battery issue. That should be good, though. Anybody have any pressing questions? All right, I'm super close. I'm stoked that you're all here on this spring break Eve. I guess it's actually spring break? I actually don't know. Is it after your classes are done? Okay, so what we're trying to learn is, okay, we want to try to understand pointer semantics, right? We want to understand what exactly are these pointer operations and what do they do, right? So we looked at both pointer dereference and the address of operator, and we saw how we can use circle box diagrams, which are really simple to show and illustrate how these semantics work. So let's look at a more complicated example. Can everybody read that? So I've got an int star star called x, I have an int star called y, I have an int called z, and then I'm going to call malloc size of an int pointer and assign that to x. I'm going to assign y, the return value of malloc of size of an int. I'm going to set x equal the address of y, y equal the address of z, y equals star x. Okay, so we're going to step through this line by line and try to see what actually happens. Before we actually show what happens, we should talk about it so that we can predict and know exactly what it should be. So this first line, so what's going to happen in the box circle diagrams after this line is executed? So if you're doing this, right, you're going through it, you say, okay, I want to use box circle diagrams to understand what's going on here, what do I do? So let's have a location x at that point in time. What x? A location that x is assigned to or maps to. I can't remember the exact language. Bound to, yeah, you could find the west. Bound, okay. So the x bound to some location, so the important point is it's some location, right, and we don't know the value that's inside that location that's bound to x, right. At this point we have no idea what's in there. Okay, and then this line, same thing with y, we just have a new name and a new location. Here's z, same thing, right. So important point here, so what's the difference between in the box circle diagrams all three of these values, these names x, y, and z? The types, yeah, but in the diagram what's the difference? Nothing, right. This is one of those fundamental concepts that you have to somehow inject into your brain or jack into the matrix and learn it or struggle with it for a while until you realize. Pointers, no dip, double pointers in star stars, right. No different than any other data type. It's just what's inside them can have a different meaning depending on if you do array act, if you do a dereference operator. So even if it's a non-primitive type. Even if it is, say that again? A non-primitive type. Yeah, so you mean for like if this was a struct? Yeah. Struct, foo, z? Yeah. Yeah, so it would just mean that what's inside here, because here we're abstracting away the exact number of bytes that's inside each of these values, so technically there would probably be more bytes, but we don't really have to worry about that. But the value where that struct is going to live is in a location that's associated with that name. So when we get to this line, right? So what's malloc? What does malloc do? Is that like kind of like a high level? Yes. So it returns the address of what? And then the box circle diagrams. The address of what box? So this box. This box. This box. Okay, so this box. It will be the box. We'll put someone else's answer. A new box. Yeah. So abstractly, right, in the circle box thing, we just need to know that malloc is going to create a new box, right? And we know that the size of whatever can be inside this new box is what's given at the parameter, right? That parameter is exactly how many number of bytes is going to be inside this circle. But for our purposes, we don't care about that when we're just talking about here with box circle diagrams about who points to what and how do we access things. So we'll say that this has an address of 4. X4. And we're writing kind of hex like this, so it's pretty clear that that's an address. So malloc does this, right? Creates this brand new location for us at some memory location. And then it returns that memory location, right? With r value of 4. And then what happens at, what is this whole assignment statement going to do? X now points, or X is now bound to that new location. X is bound to the new location? How the diagram changes, that was the case. So this would be... Let's see if I can do this with this terrible thing. This is going to fail. We'll try this, right? This would mean that this name X is now bound to this location. Points to it. The value inside of X now has that memory location. Yeah, so the value... So this is the way to bring it down. This is why we kind of built it up into little steps, right? So we know the exact semantics between L value equals r value. So here on the left is X and L value and r value. L value. There's a location here associated with X. And so malloc returns an r value, which is 4. The address of this new memory location. And so then if we have L value is equal to some r value 4, what do we do? Yeah, just take, exactly, exactly. That's a good semantics. So take the 4, store it in the location associated with the name X. Right? And so that's going to be 4. So then then... So where does now... Does anybody have to erase this red line? I wonder if I can just move it a little bit. Go away. Success. Restart. Fixes everything. So now that this 4 is inside the value associated with X, if I were to do star X, where does that point to now? 4. So it points to here? The value inside of there. The value inside of here? Yes. So star X is going to point to the circle? Yes. What is the dereference operator return? Return of value or location? A location. So what's it going to point to? Location that X is associated with. So whatever it is. The location that star X is going to point like here? Yeah. The box at 4. Yes. The box at 4. Right? So specifically, star X is going to point to the box. Right? And this is Y. So the dereference operator is a location. Right? So that's exactly why we can use this on the left-hand side of an equation and to be able to write to it. We can access the value in here. If we use star X on the right-hand side of an equation, it's going to get the value associated with the location star X. And so it's going to be able to get that value out of there. But we can use it on the left-hand side because it specifically points to the box. So it looks up 4 and it says, okay, give me the location associated with the memory address 4. Okay. Now, two dead batteries and one half dead, recorded dead battery. But let's try. It's awesome when people put batteries in a computer marked new that are actually old. I haven't yet got to the case from lugging around batteries in my bag, but I'm sure I'll get there at some point. I have markers in there too, just in case. Ready to teach at a moment's notice. Okay. So is that everything that's done? Now, in the semantics here? Yeah. We've taken that value, we've assigned it there. So remember, this star X doesn't actually, we haven't used that in the program yet, but you can see that this is where star X points to. And because this is semantics and because it matters a lot, you have to be precisely correct in these things. So on a midterm or something, if we're like, okay, draw the circle box diagrams at this point in the program and label like star X. If you draw star X going to the circle, star X points to the location because it's an L value. Okay. So then what's going to happen here on this Y? New memories? So Malik's going to create a new memory, so how am I going to draw that? New box. Yes, so we get a new box. It's going to be some memory address. We'll call it location eight. We'll consider that it's four bytes away, but really these could be completely abstracted. They could be whatever. It doesn't really matter except that it's different from those other addresses. And then what's going to happen after Malik creates this value? Associated with Y. Yes, so eight is going to be copied into the location associated with Y and now where does star Y point to? At the memory address eight. These are all pointers R. And then are we done? With this line? Yes, it's a 50-50 question as well. Yes. Okay. Now what's this line going to do? Change the value inside of X. Change the value inside the location associated with X? Yeah. With to what? To Y's address. To Y's address. Yeah, so we actually haven't given, we'll call them, we'll call them addresses, the address of X, the address of Y, the address of Z. It doesn't matter how you do this, right? On a midterm or something, we'll usually tell you, assume X is at some memory address, alpha or address of X is usually actually a super easy way to do it. So now that we've given them these names, then what's going to happen? What are we going to do? So what is that address of Y return? A, D, Y. Yeah, remember address of operator returns an R value. So it takes in a box, right? It takes in a location, and it gives you the address, which is an R value associated with that location. So it's going to return the address of Y, and then that's just some value. So where's it going to put that value? Circle in X. Yeah, in the circle in X. So now where does star X point to? That also has the name Y, right? So now it's going to point here. So what happened? What happened to the location of the memory associated at four? Did we touch that or change that? It's leaking. It's leaking. Why is it leaking? Because we didn't refer you. Right, so a key problem, well, we're going to get into it in a second, but this kind of is forward shadowing, a foreshadowing, right? So is there any way we can reference this location four now? No. Maybe. We can iterate through overall possible memory locations, right? But, you know, semantically from here, there's no way. So in our program, right, we can only access X, Y, and Z, the names X, Y, and Z, right? And then from there, we can access their dereferences, right? So we can dereference any of those pointers. So we can go to anything they point to. We can go to anything those things point to. But how do we get from X, Y, and Z to star four? Sorry, star. The location at the memory address four? No, we can't. Yeah. So this is basically a memory leak. The problem is, or it's, yeah, it's a, trying to remember the exact term we used. We'll see in a second. But it's essentially a memory leak. So we have created some memory, right, that can no longer be accessed by our program. So how do we access this O8, OX8? So we can use Y, and then we can do Y star, right? And so that'll get us there. Or star, star, X, yeah. So we can go X, and then star, star, X to get here. So that's fine. But four we can never reach. But let's continue executing. We'll kind of set that aside by now. Okay, we get to this line. Y is equal to the address of Z. So what's going to happen here? Yeah. So what's the address of Z? ADZ. ADZ. And so that's an L value and an R value. R. R value. Yeah. So it's an address. It's just some value. And so we're going to copy that value where? Circle of Y. The circle and the location associated with Y. So we take that. We're going to erase that. And so what's going to happen to our, to star Y? Wins to Z. It's going to point to the location associated with Z. Yeah, right? So star Y is now going to point to the box Z. So what's going to happen here? The value of ADZ is going to equal the, or is going to be changed to the value of ADZ. Yes. Okay. So let's bring it down. So star X, what's that going to return an L value or an R value? R value. L. L. Always L. Stars. De-references. Always L. Click to click to shop. Always L, right? That's why it points to this whole box. Right? So star X is going to return this box. And so we have an L value, right? Y has a location associated with it. And on the right hand side of that assignment operator, we also have an L value, right? A location. So take the value inside star Y, which is ADZ. Copy it into the look, value of the location associated with Y, which is this box. And so we copy ADZ and put it back into ADZ. Questions on what happened here? So this box is star X. What's the value inside the box of star X? ADZ. Right? Because star X means take X, take the value inside of X, look up that, find me a box with the address of ADY. So which is the box here with the address of ADY? Not Y. Why's the name? The location associated with Y. Right? So it's this box. So star X is going to refer to this location. So we have basically the location associated with Y. Assign that whatever is in the location associated with star X. So star X, we get the value in that location, which is what's the value of the location star X? ADZ. ADZ? We take ADZ, where are we copying it? Location associated with Y. Yes. Into the location associated with Y? So this is the location associated with Y? And the value? So we copy ADZ into there? In effect, nothing changes. But yeah, we have to know. I mean, to know that nothing actually changes, right? We have to know that X is the address of Y, or X has the address of Y. So that when we dereference X, we're talking about that same location. And this is why pointers make analyzing C code very difficult, because there can be multiple ways you can reference something. So if I want to ask the question in my analysis, hey, is it ever the case that this value could be zero? Well, you know, if the value inside Y could ever be zero. Well, it could be zero if you set Y equal to zero, which is easy to tell. But is there any possible way that all pointers that point to Y, did they ever change their value to zero? So it becomes very difficult. Then let's add on to this program, make it a little more complicated. Let's hit Z equal to 10. So what's this going to do? 10 and the circle for C is location associated with Z. Yes. Take 10, copy 10's in R value, copy it into the location, the value of the location associated with Z, which is right here. We're going to put 10 in there, and we're going to print out star star X. So where's star X? What does star X refer to? The location associated with Y. Yeah, the location that has the address of Y, which is this box. And then what is the star of this box? The location associated with Z. Yes, you take the address of Z, the value in here, look up the location associated with it. It's here. And so when we print it out, we're accessing the value in star star X star, or star star X. One dereference and then dereference this location. So we get this location. And so we print out 10. Does that make sense? Then we say star Y equals 100. So how do we get star Y? How do we figure it out? Not the thing that it points to. The value that's inside the location associated with Y. When we say what Y points to, we would say this. So Y is a location, has a location associated with it. There is a value inside of there. So when we do star Y, should be star Y, that should be switched. We're going to look up the value in, I should have fixed that now, otherwise I'll never forget, or I'll never remember. Okay. So we're going to get this, the value in the location associated with Y, ADZ, then look up, are there any locations with the address ADZ? This one, right? This location. And so we're setting, so this is the L value, and on the right-hand side, we have 100. So we're having 100 into this location. So we just take 100 and put it where? In the circle here? Yeah. How would this change if the value associated with Y was, like an integer and seven address? Would you try to look up the address of the integer, and do this? Just like with the fours and the eights. Yeah, I mean at the end of the day, we're only representing this like ADZ, ADY, because we don't, we're trying to say we don't know necessarily beforehand what those addresses are, but they are just integers. Yeah. That's the important thing. So we could look up, and look up the value. Exactly. Yes. Yes. That's how you get the problems. But that's all first. Yay. Okay. So we're going to copy 100 into here, right, into location associated with star Y, and then when we print out Z, what's it going to print out? 100. So, we kind of saw it here. So why, why, when I change star Y, why did Z change? It was associated with the location of Y contained in the address of Z. Okay. Yes. And what does that, so star Y, right, the expression star Y and Z, what do they both refer to? Unaddressed. The box. Yeah, location, right? Yeah, they both refer to the exact same location. So that's another way to think about it, right? Is Z refers to this, Z is bound to this memory location, and star Y references that same location. What about star star X? Yeah, it's actually another name for this location, right? So what we call these, we call these aliases. So this means that they are different names for the same location. So an alias is, yeah, two L values, so two different names, two different L values that have the same location. So at the end of execution, so what are all the aliases here? If I asked you on a test or midterm, you said, okay, here's a program at this point, what are the circle diagrams, what are the aliases at this point, and then what are the aliases at the end? So at the end of program execution, what are all the aliases here? We'll do pairs of them. For X. For X. Wait, what's the alias for X? X. That's the same name, so. Not as interesting. You can ignore aliases, yeah, they have to be different expressions or L values. Star X and Y. Star X and Y. Yeah, so star X also refers to the same location, so we have star X and Y. What are the other ones? So we have Y, star, and Z. What was the other one we said? Star, star, X. Star, star, X and Z. So these are all the same. Star, star, X. Okay, so let's look at them. I think there's some, what were some questions that we were talking about with this? I just thought like, hey, I should do an example after this, but I couldn't remember. Nobody remember? Do you have any questions on this? Yes. If you were to do star Z equals 50, does that mean it would try and go to the memory location 100 and put 50 in the value there? Yes, that's exactly what happens. Yes, okay, yes. So that's some of the things I want to look at. So if we had, if we had a program like, yeah, so if we said Z equal to 100, and we said star Z is equal to 50, like this, and we may need to do, if we actually wanted this to compile, right, we have to cast Z to an int star. So that would return, because the compiler's type system says, hey, you can only dereference a pointer data type, right? But this is just an integer. But Z will allow us to say, hey, I know you think this is an integer, but trust me, it's really an int pointer. And so this is exactly what it's going to do. So if we draw the box circle diagrams, we have our Z, right? We have our box. The value we put inside here is 100 at this line. And then when this line executes, it's going to try to look up any memory address, some memory address that has the value 100, and then set that value equal to 50. So if we can do that, it'll actually succeed, and it'll work just fine. If it doesn't, if it can't find something, then it's at fault. So this is also where you can get segmentation faults. So let's look at, and actually this is a good point. I want to look at some other code. So if I had code like this, let's say I have share our pointer, test. Ooh, always fun to do that, right? Okay, so we have a character pointer called test, and we want to say, what happens when we do, well, maybe this isn't the best, we change that, I think it's in read-only memory. Maybe we can write to it. Let's, let's leave it like this, whatever. It's just a simple example we can do whatever we want. Okay. So what actually happens here? So are there any pointer dereferences that are happening here? I explicitly know, but an array access is very similar. Is it very similar? How similar is it? Did you know you can write your array accesses like this? Do you believe me? Ooh. Let's, let's write some code. All right, I wasn't planning on doing this. Always fun to do coding exercises live. Test.c pound include. We need to be able to look at things. So we want standard io.h code up in main. What I say, character pointer test is equal to something like this. And what I say, test zero is equal to a, test five is equal to b, test three. So we'll print out the string first, percent s, test. So what's the percent s in the printout doing? Print out a string. Is that a string? Character? So let's see what happens. All right, we're going to not use, is everybody okay with us not using sento s for this and using the Mac compiler? It's found c code, it should be the same, right? And of course I say that, it's going to all blow up in my face. Successfully files. It's going to happen when we run it. What's the output going to be? Cs3 to 4 to you. And then the modified string? So it's going to be a s, I can't actually tell. a s e c 3 b exclamation point. Does everybody agree? Is it going to crash? I actually don't know 100% what's going to happen, but this is what I programmed. The only thing I'm worried about is this string, because it's a constant string, I don't know if it stores it in read-only memory. So I don't know if altering that, but I actually don't. Maybe it stores it as a global string. Yeah, it should be fine. Let's run it. No. Interesting. Okay, so when you get this, this one you want to make sure that it actually does it on the right thing. Why is it 3 test? Huh? On code you have 3 test? Yes, because I'm making a point. I just haven't made it yet. Okay. There we go. Okay, compile. So it did put it in there. Tricky, we all learned something there. I think, let's check. Just to make sure that there wasn't something like that. It's still acceptable. Can you initialize a character array using quotation and you still access it? That's what I'm thinking, no. I'm thinking it's... So you had to do it with the curly string. String.h. We can do it quick. We'll just duplicate the string. So we're trying to copy the string and then we should be able to do whatever we want to. Is this going to work? The string in string.heil or string.h. How do I find out if I want to know what header file defines string. Google it. Google it. Way quicker way. I have to go all the way to Google and I know you don't have my browser open but I don't want to show my browser to you guys because it's weird. All of your beautiful Linux machines comes with an entire manual that has manuals for every single function and every single batch command. So you can just do man string do. Look at it, it tells you exactly how to include string.h. It tells you all the functions. It tells you how you want to duplicate it, everything. There are examples on how to use it. It'll tell you that of course my font is big but it'll tell you that it calls malloc to allocate the memory for the string but that means that you have to make sure you call three. If you want to look up what does malloc do? You call malloc and you can read all the things and you'll be like, oh if I want to call malloc I need to use standardlib.h. Look at this, so much faster than Google search. ASIC4V. Okay, that was successful. So why? So what's happening here? Let's see. Can I just copy this? I'm actually surprised that worked. Okay, so what's happening? Why did that work? It's close to the assembly style way of doing it. It's close to the assembly style way of doing it? So what's my box circle diagram look at this line for test? What does test look like? A constant string is assigned to a new memory location and then the test test gets its own box. Yes, test is bound to some location. Do we know the location? No. We don't really care. We'll follow it. What's the value inside test? Nothing yet. Let's say before this assignment operator happens, right? So there's something in there. We don't know exactly what it is. Right? And so CSE340 is going to be stored somewhere. Right? That's going to be maybe location beta. And what is string dupe going to do? Copy it to a location. Copy to a new location. Yeah, exactly. So it's going to copy that whole string so it's going to create a new location with enough... I'm running out of Greek letters. What's that for beta? Oh, that's right. Okay. I have to look at it all again. It's an upside down. It's an upside down? We'll... Just do lambda. Lambda is good. It's going to get confusing. We'll get to lambda. Okay. So we have CSE340 exclamation point. And technically, there's actually a zero byte here right at the end because C-style will terminate the strings. So there'll be a zero byte there. So... Okay. Then what... So then string dupe is going to create that and return lambda. And so what does this assignment do? It assigns the circle to lambda. Yeah. Which circle? There's three circles here. Yeah. Well... You want to do the whole thing? Not really. Let's go practice. The search... The location associated with tests is going to add lambda into that, right? So test is... as the value of lambda. So where does star test point to? Which location? This one? Yes. So we print it out. It's going to print out this whole string. So the percent s is actually going to iterate over the string length and it's going to print out basically tests. Test zero as a test zero as a character, because that's true as a character all the way until it gets to a zero byte. So then how does that access work? So when I see this line specifically test zero is equal to a. Yeah. So first, what is the array access actually doing? What are the semantics of the array access? It dereferences. Dereferences what? The... Dereferences So can you rewrite this into equivalent valid C code that's more of what actually happens? Yes. Star what? It would be multiplied by something. Zero times something. Size of? Yeah, size of. So where are the parentheses on this, like this? Like this? Yeah, so this actually... So somebody were talking about size of at the C level you don't have to worry about that because pointer arithmetic will automatically increment the pointer the size of whatever the pointer is so that's why if you do test plus zero test plus zero is obviously test. Right? Okay. So what is the character... What is... What's the data types of star test? Character. Yeah, how big is a character? How many bytes? A single byte. How many bytes do we have in here? 1, 2, 3, 4, 5, 6, 7, 8 8 bytes in here. So what's test plus zero doing this arithmetic? What's that going to be? Test plus zero? Test. Lambda. It's just lambda, right? So what's star lambda then? C. Yeah, so it's a little bit tricky, right? Because this is actually an array of contiguous elements. So really if we wanted to draw this more precisely we would have lambda, the value inside there is the character C. Yeah, so what's this address? Lambda plus 1. Lambda plus 1 is going to have the character S and lambda plus 2 is going to have the character E and so on all the way through, right? So the location of lambda is actually this guy. Right? So star test actually points to this guy. And so we do test plus zero is lambda. Right? Because the address the value inside the location associated with test is lambda. And then we dereference that. So we look up, okay who, where is the location associated with lambda? Oh, it's here. So then I'm going to change that to be what? Character A, right? Which is going to be some specific bit pattern. And then our more abstract model here that's going to change this to be right? Okay. So what about the next line? Test 5 is equal to B. So what's that equivalent to? Or test plus 5. Yeah, start test plus 5. So test plus 5 is lambda plus 5. Lambda plus 5. Right? So lambda plus 5 is 0, 1, 2, 3, 4, 5 here. So I'm going to set that to be what? B. B. So we're going to change this to be B. And now 3 test equals C. So what's that? What's 3 test equivalent to? Star 3 plus test. Is it any different from any of these cases? No, it's exactly the same. So what's 3 plus test? Lambda plus 3, the value lambda plus 3. And so star lambda plus 3 is going to return that location that's associated with lambda plus 3. Lambda plus 3 is 0, 1, 2, 3 here. And it's going to set that equal to C. 0, 1, 2, 3. And now we print that out. This should be the string that we printed out, right? So this is, so specifically the array access is just syntactic sugar for for doing pointer arithmetic. So it's saying like start at test, go 5 elements down, and the size that this actually moves in terms of memory depends on the size of the thing that's being pointed to. In this case, it's character, so it's actually just bytes, so it's going to offset it by 1. Actually by 1 when it goes back to memory. So it makes sense to me if you have the name of the array and then you have the parameter how much to add. But why would they also give you the option of doing it the weird 3 brackets with the name of the array inside? Just simple. So the question is, so in this case maybe it's clear because it's a value. But what if we had code that was like I mean then you have to kind of be more careful about who's what and all this kind of things. It's honestly just A for probably consistency purposes and the fact that all this is is a translation to this. Or all that these are just merely translations for this. So that's why when I mean that it's syntactic sugar what that means is that there's already a way to write this expression in the C language. This thing that you can do here you can do just like this. But it's a little more cumbersome and it doesn't quite convey exactly what you want to do. So they allow you a super easy way like this and they just translate between the two. Or not between but they just translate very clearly between the two. If they were thinking far ahead of like oh everyone in the world is going to be using C code and C applications then yeah it would be nice to use the type system to say no actually with the array access you have to have only you know an int or something like that in the access but it just looks really weird. So C is still valid. C is just written such that when you have an array access where you have something with the brackets and then something else in the brackets you're just adding the two and then finding the value with that location. Yep. It's exactly equivalent to this. So similarly if I have a if I have a struct a pointer to a struct food called test or we're running out of tests so we have a variable name and a handlebar. 10. Well it's not temporary though. Okay so two pointer, malloc, size of okay I think that's mostly right right so we're going to create some new thing and now when I do 10 if I do 10 equals one of the let's go bar right when I do this this is actually also syntactic sugar for start it's actually start temp I don't know what to say to this start temp.bar right because if I struct struct food called not temp right I could I could access element bar by not temp.bar right is equal to 10 so all of this so this arrow access is just syntactic sugar for this so it does automatic translation for dereference the thing on the left and then turn it into a structure access for the thing on the right this is all this does and then you can combine them together right so you can be like array i and that'll be something like array plus i so this will be star of that and then take that whole thing or dereference let's see dereference that whole thing right and then call access structure bad right so this actually has two pointer dereferences right so array is going to be a pointer to an array a pointer of structures this makes sense alright I think we've covered a lot today I'm actually super happy cool alright have a good spring break see you next Monday