WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000 00:00:00.000 --> 00:00:03.792 [MUSIC PLAYING] 00:00:05.392 --> 00:00:07.100 DOUG LLOYD: So in this video, we're going 00:00:07.100 --> 00:00:10.370 to talk about how to dynamically allocate memory in C. 00:00:10.370 --> 00:00:13.250 Now, as a disclaimer, if you haven't watched our video on pointers 00:00:13.250 --> 00:00:15.320 or aren't generally familiar with the concept of pointers, 00:00:15.320 --> 00:00:17.730 you're probably going to want to take a look at that before this. 00:00:17.730 --> 00:00:20.000 This video, dynamic memory allocation in general, 00:00:20.000 --> 00:00:21.830 works specifically with pointers. 00:00:21.830 --> 00:00:23.705 So you're going want to make sure that you're 00:00:23.705 --> 00:00:26.660 comfortable with that before diving in to this particular video. 00:00:26.660 --> 00:00:28.395 Without further ado, let's get started. 00:00:28.395 --> 00:00:30.770 Now, we've already seen how to work with pointers before. 00:00:30.770 --> 00:00:32.769 But typically, we've only done it in the context 00:00:32.769 --> 00:00:36.154 of pointing a pointer variable that we declare statically 00:00:36.154 --> 00:00:37.820 at another variable that already exists. 00:00:37.820 --> 00:00:39.570 You may recall from our video on pointers, 00:00:39.570 --> 00:00:41.300 we had a line like int x equals 5. 00:00:41.300 --> 00:00:45.029 And then we would say int star px equals ampersand x. 00:00:45.029 --> 00:00:47.570 But that's the only way we've seen how to work with pointers. 00:00:47.570 --> 00:00:50.900 And that's static pointer usage, basically. 00:00:50.900 --> 00:00:53.166 In order to work with pointers statically as we have, 00:00:53.166 --> 00:00:55.040 we need to know exactly how much memory we're 00:00:55.040 --> 00:00:58.190 going to use at the moment we compile our program. 00:00:58.190 --> 00:01:00.530 So we're not going to be creating any memory on the fly. 00:01:00.530 --> 00:01:04.647 All the memory that we're going to use is already set up when we begin. 00:01:04.647 --> 00:01:06.230 That presents sort of an issue, right? 00:01:06.230 --> 00:01:08.660 What if we don't know how much memory we're going to have when we get 00:01:08.660 --> 00:01:09.590 started? 00:01:09.590 --> 00:01:13.250 Maybe you're going to be asking the user to give you a number 00:01:13.250 --> 00:01:16.275 and they're going to generate a hundred linked list object. 00:01:16.275 --> 00:01:19.400 So they're going to generate hundreds of something and you don't know that. 00:01:19.400 --> 00:01:21.372 Or maybe they generate 200 or 400. 00:01:21.372 --> 00:01:23.330 We wouldn't be able to predict this in advance, 00:01:23.330 --> 00:01:25.850 and so we need to use dynamic memory allocation in order 00:01:25.850 --> 00:01:29.460 to get new memory in our program while the program is already running. 00:01:29.460 --> 00:01:32.210 And that's a little bit different than anything we've seen before. 00:01:32.210 --> 00:01:35.150 We can do this by allocating memory from something called the heap. 00:01:35.150 --> 00:01:37.121 The heap is a giant pool of memory. 00:01:37.121 --> 00:01:39.620 And so far, the only pool of memory that we're familiar with 00:01:39.620 --> 00:01:41.330 is called the stack. 00:01:41.330 --> 00:01:45.017 But dynamically allocated memory comes from the heap and statically allocated 00:01:45.017 --> 00:01:47.600 memory-- which is anything that you give a name to, typically, 00:01:47.600 --> 00:01:49.190 like a variable name-- 00:01:49.190 --> 00:01:50.750 is going to be set up on the stack. 00:01:50.750 --> 00:01:53.666 And anything that you create dynamically while your program is running 00:01:53.666 --> 00:01:55.462 is going to come from the heap. 00:01:55.462 --> 00:01:57.920 But as we can see from this diagram, the stack and the heap 00:01:57.920 --> 00:02:00.500 are actually the same big chunk of memory. 00:02:00.500 --> 00:02:03.710 It just so happens that the stack we allocate from the bottom to the top, 00:02:03.710 --> 00:02:05.210 typically, to visualize it. 00:02:05.210 --> 00:02:09.350 So the stack memory addresses will be a bit lower numbers and the heap 00:02:09.350 --> 00:02:12.214 will have higher numbers and it'll allocate downward. 00:02:12.214 --> 00:02:15.380 So it's really one giant pool of memory, but we call it two different things 00:02:15.380 --> 00:02:16.754 depending on how it's being used. 00:02:16.754 --> 00:02:21.260 The stack for statically declared memory grows up and the heap for dynamically 00:02:21.260 --> 00:02:24.115 allocated memory grows down. 00:02:24.115 --> 00:02:26.240 How do we get at this dynamically allocated memory? 00:02:26.240 --> 00:02:28.130 How do we access memory on the heap? 00:02:28.130 --> 00:02:31.400 We need to use a new function called malloc. 00:02:31.400 --> 00:02:34.520 You can get malloc by pound including standard lib.h, stdlib.h. 00:02:36.992 --> 00:02:39.200 And the only argument that you need to pass to malloc 00:02:39.200 --> 00:02:42.060 is how many bytes of memory that you want. 00:02:42.060 --> 00:02:44.420 So if you want an integer, you say malloc 4. 00:02:44.420 --> 00:02:46.460 If you want a character, you malloc 1. 00:02:46.460 --> 00:02:48.960 If you want to double, you malloc 8, and so on. 00:02:48.960 --> 00:02:51.770 And you can be more complex than that, as we'll soon see. 00:02:51.770 --> 00:02:54.530 What malloc will then try and do is find some chunk of memory 00:02:54.530 --> 00:02:57.570 the size that you asked for on the heap. 00:02:57.570 --> 00:03:00.255 So it'll go and try and find eight contiguous bytes of memory, 00:03:00.255 --> 00:03:00.755 for example. 00:03:00.755 --> 00:03:04.088 If we're allocating a double, it will go and try and find eight contiguous bytes 00:03:04.088 --> 00:03:05.630 of memory from the heap. 00:03:05.630 --> 00:03:09.862 And what it will do is it will return to you a pointer to that memory. 00:03:09.862 --> 00:03:13.070 So the only way we're going to be able to access dynamically allocated memory 00:03:13.070 --> 00:03:16.514 or use it is by dereferencing the pointer that we get back from malloc. 00:03:16.514 --> 00:03:18.680 And that's why it's important to understand pointers 00:03:18.680 --> 00:03:20.300 before going forward. 00:03:20.300 --> 00:03:22.490 Now, it's possible that malloc might not actually 00:03:22.490 --> 00:03:24.505 be able to give you back memory, in which case 00:03:24.505 --> 00:03:25.880 it's going to return to you null. 00:03:25.880 --> 00:03:28.755 And so one of the first rules to remember about dynamically allocated 00:03:28.755 --> 00:03:32.105 memory is to always check for null after malloc. 00:03:32.105 --> 00:03:33.230 Now, why might this happen? 00:03:33.230 --> 00:03:34.280 Maybe you've run out of memory. 00:03:34.280 --> 00:03:35.810 The stack and the heap have just completely 00:03:35.810 --> 00:03:38.240 run out or there's been some sort of catastrophic failure 00:03:38.240 --> 00:03:39.590 that we can't predict. 00:03:39.590 --> 00:03:41.840 But either way, if you recall from our pointers video, 00:03:41.840 --> 00:03:43.662 dereferencing a null pointer, bad news. 00:03:43.662 --> 00:03:46.370 So the first thing you want to do-- after you malloc, of course-- 00:03:46.370 --> 00:03:48.690 is to check to make sure that you didn't get back null. 00:03:48.690 --> 00:03:51.950 And if you did, you're going to need to abort your program because something 00:03:51.950 --> 00:03:55.350 has gone wrong and you can't proceed with what you currently have. 00:03:55.350 --> 00:03:58.580 So if we want to just get an integer, statically declare it, 00:03:58.580 --> 00:03:59.840 we can just say int x. 00:03:59.840 --> 00:04:02.870 That's going to create a variable called x on the stack 00:04:02.870 --> 00:04:05.360 that we can then assign any value that we like to. 00:04:05.360 --> 00:04:08.000 If you want to dynamically allocate an integer, 00:04:08.000 --> 00:04:11.851 we say the following-- int star px equals malloc 4. 00:04:11.851 --> 00:04:13.850 And the reason we say four here is because there 00:04:13.850 --> 00:04:16.519 are four bytes in an integer. 00:04:16.519 --> 00:04:21.019 I easily also could have used the sizeof operator, which is available in C. 00:04:21.019 --> 00:04:22.499 Basically, you pass it a type-- 00:04:22.499 --> 00:04:23.790 so it's a little bit different. 00:04:23.790 --> 00:04:25.760 Usually with functions you pass in a variable. 00:04:25.760 --> 00:04:27.290 With malloc, you pass in-- 00:04:27.290 --> 00:04:30.070 or with sizeof, rather, you pass in a type 00:04:30.070 --> 00:04:33.790 and it will return how many bytes that type takes up on the system. 00:04:33.790 --> 00:04:37.370 So int star px equals malloc size of int or int star ps 00:04:37.370 --> 00:04:40.280 equals malloc 4 basically means malloc going 00:04:40.280 --> 00:04:42.510 to go try and find you four bytes of memory that 00:04:42.510 --> 00:04:44.900 are next to each other on the heap. 00:04:44.900 --> 00:04:48.749 And malloc will return to you a pointer to that memory called px. 00:04:48.749 --> 00:04:50.540 And then we could dereference that pointer, 00:04:50.540 --> 00:04:54.350 as we've seen in the pointers video, to manipulate it, to put a value in there, 00:04:54.350 --> 00:04:56.304 to do whatever we want to do with it. 00:04:56.304 --> 00:04:57.720 Let's see another example of this. 00:04:57.720 --> 00:05:00.120 Maybe we want to get an integer from the user. 00:05:00.120 --> 00:05:03.350 So recall that CS50 we have the get_int function that we can use. 00:05:03.350 --> 00:05:04.830 Int x equals get_int. 00:05:04.830 --> 00:05:08.020 We're basically prompting the user for some integer value. 00:05:08.020 --> 00:05:09.790 And it'll give us some number, hopefully, 00:05:09.790 --> 00:05:12.160 in this example, a positive number. 00:05:12.160 --> 00:05:16.150 Let's say I want to declare an array of that many floats on the stack. 00:05:16.150 --> 00:05:18.760 I can do this by saying float stack_array and then in square 00:05:18.760 --> 00:05:21.230 brackets-- which, again, indicates the size of the array-- 00:05:21.230 --> 00:05:21.970 x. 00:05:21.970 --> 00:05:23.875 This is legal in C 99 and C 11. 00:05:23.875 --> 00:05:25.750 If you're using a very old version of C, this 00:05:25.750 --> 00:05:27.730 was actually previously not allowed. 00:05:27.730 --> 00:05:28.570 But you can do this. 00:05:28.570 --> 00:05:33.010 We can basically get a variable-sized array 00:05:33.010 --> 00:05:35.560 on the stack, which we're doing here because we don't know 00:05:35.560 --> 00:05:36.760 how big it's going to be in advance. 00:05:36.760 --> 00:05:37.820 We're just getting it from the user. 00:05:37.820 --> 00:05:39.945 But this is how we would declare an array of floats 00:05:39.945 --> 00:05:42.580 on the stack where the number of items in that array 00:05:42.580 --> 00:05:44.640 is the number the user just gave us. 00:05:44.640 --> 00:05:47.812 And I can also dynamically allocate an array of floats on the heap-- 00:05:47.812 --> 00:05:50.020 not on the stack, remember, because we're dynamically 00:05:50.020 --> 00:05:51.680 allocating the memory this time. 00:05:51.680 --> 00:05:52.810 Float star heap_array. 00:05:52.810 --> 00:05:55.740 So that's my pointer to the memory that I'm getting. 00:05:55.740 --> 00:05:58.390 And I want to malloc x times the size of a float. 00:05:58.390 --> 00:06:01.900 So if I want to have 50 floats, I need 50 times the size 00:06:01.900 --> 00:06:03.940 of a float, so 50 times 4. 00:06:03.940 --> 00:06:06.310 Maybe I want 100, so it would be 100 times four. 00:06:06.310 --> 00:06:08.435 So that's why we're doing the multiplication there. 00:06:08.435 --> 00:06:11.200 And malloc is going to return to us one giant block of memory 00:06:11.200 --> 00:06:16.581 that size, which we can then just treat like any other array. 00:06:16.581 --> 00:06:19.080 There's one catch with dynamically allocated memory, though, 00:06:19.080 --> 00:06:22.246 that we have to deal with, and that's something that we haven't seen before, 00:06:22.246 --> 00:06:25.990 and that is that it is not released back to the system when you are done. 00:06:25.990 --> 00:06:30.280 So if you haven't yet seen our video on the call stack or stack frames, 00:06:30.280 --> 00:06:32.290 this might not be something you're aware of yet. 00:06:32.290 --> 00:06:35.110 But typically, when a function finishes running, what happens 00:06:35.110 --> 00:06:38.260 is all of the memory that was created for purposes of that function's 00:06:38.260 --> 00:06:41.107 existence gets destroyed and it is released back to the system 00:06:41.107 --> 00:06:42.190 to be used somewhere else. 00:06:42.190 --> 00:06:45.620 So another function call that might come up can use that same bit of memory 00:06:45.620 --> 00:06:46.120 before. 00:06:46.120 --> 00:06:47.495 That's kind of convenient, right? 00:06:47.495 --> 00:06:50.710 This system is constantly recycling where it can. 00:06:50.710 --> 00:06:53.950 But when you tell the system, I want a block of memory, 00:06:53.950 --> 00:06:56.720 the system is not going to assume anything about it. 00:06:56.720 --> 00:06:59.680 It's not going to assume that it hasn't seen you make a call with it 00:06:59.680 --> 00:07:03.677 for 50 lines or whatever, and it's just going to dynamically free 00:07:03.677 --> 00:07:05.729 it or release it back to the system. 00:07:05.729 --> 00:07:08.770 And if you fail to release enough memory back to the system, what you get 00:07:08.770 --> 00:07:10.741 is something called a memory leak. 00:07:10.741 --> 00:07:13.240 And memory leaks are really not good because they can really 00:07:13.240 --> 00:07:14.520 slow down your system. 00:07:14.520 --> 00:07:16.480 And in fact, there are some browsers that 00:07:16.480 --> 00:07:21.400 shall remain nameless that are sort of notorious for not freeing memory or not 00:07:21.400 --> 00:07:24.454 releasing memory back to the system when it's done. 00:07:24.454 --> 00:07:26.620 And that can really cause your computer to slow down 00:07:26.620 --> 00:07:30.310 because that browser is basically hogging a bunch of memory 00:07:30.310 --> 00:07:32.841 and the other programs on your computer can't use it 00:07:32.841 --> 00:07:35.090 because the browser has sort of allocated it and said, 00:07:35.090 --> 00:07:35.830 no, this is mine. 00:07:35.830 --> 00:07:36.810 I need it. 00:07:36.810 --> 00:07:38.830 But it never releases it back to be shared 00:07:38.830 --> 00:07:40.246 by the other things on the system. 00:07:40.246 --> 00:07:42.430 So that's why if you leave a browser open for days-- 00:07:42.430 --> 00:07:44.650 or some browsers open for days or weeks-- 00:07:44.650 --> 00:07:47.740 you might notice your computer starts to slow down. 00:07:47.740 --> 00:07:49.960 Now, the rule is, as I've mentioned before, 00:07:49.960 --> 00:07:52.240 when you're done working with dynamically allocated 00:07:52.240 --> 00:07:54.640 memory, all you have to do is free it. 00:07:54.640 --> 00:07:57.880 And free is another function that is available in standard lib.h. 00:07:57.880 --> 00:08:01.090 And basically what you passed to free is a pointer to any memory 00:08:01.090 --> 00:08:03.340 that you have dynamically allocated previously. 00:08:03.340 --> 00:08:05.830 And basically that's just telling the system, I'm done. 00:08:05.830 --> 00:08:08.029 You can use this memory for whatever you'd like. 00:08:08.029 --> 00:08:09.820 So here's another example let's say we want 00:08:09.820 --> 00:08:12.730 to malloc a 50 character long array-- 00:08:12.730 --> 00:08:14.230 so basically a big string. 00:08:14.230 --> 00:08:15.420 We're going to call it word. 00:08:15.420 --> 00:08:16.682 We dynamically allocate it. 00:08:16.682 --> 00:08:18.140 Then we just do some stuff with it. 00:08:18.140 --> 00:08:20.752 Maybe we were in the middle of a function. 00:08:20.752 --> 00:08:22.210 You know, we're changing its value. 00:08:22.210 --> 00:08:23.230 We're assigning new characters. 00:08:23.230 --> 00:08:24.730 We're printing it out, for example. 00:08:24.730 --> 00:08:26.350 And then we decide that we're done with it. 00:08:26.350 --> 00:08:28.099 How do we release this back to the system? 00:08:28.099 --> 00:08:29.140 We just need to free it. 00:08:29.140 --> 00:08:30.517 So we free word. 00:08:30.517 --> 00:08:32.350 Word is the pointer to that block of memory. 00:08:32.350 --> 00:08:34.645 That's the thing that we want to free. 00:08:34.645 --> 00:08:37.929 So there are three basic rules for malloc and free 00:08:37.929 --> 00:08:39.820 that are really important to internalize. 00:08:39.820 --> 00:08:42.100 The first is that everything that you malloc 00:08:42.100 --> 00:08:44.650 has to be freed before your program finishes running. 00:08:44.650 --> 00:08:47.170 Now, granted, if your program actually finishes 00:08:47.170 --> 00:08:50.660 running, once it's completely done, once you've returned zero from main, 00:08:50.660 --> 00:08:52.820 for example, then it will be freed. 00:08:52.820 --> 00:08:55.250 But it's a good practice to make sure that everything 00:08:55.250 --> 00:08:59.582 that you allocate you specifically free by explicitly calling 00:08:59.582 --> 00:09:02.290 the free function, as opposed just relying on the system to do it 00:09:02.290 --> 00:09:04.960 once your program is completely done. 00:09:04.960 --> 00:09:08.260 So everything that you malloc, you have to free. 00:09:08.260 --> 00:09:11.957 Rule number two, only things that you malloc are things that you should free. 00:09:11.957 --> 00:09:14.790 So if you statically declared a variable, you don't want to free it. 00:09:14.790 --> 00:09:17.290 The system is going to take care of releasing 00:09:17.290 --> 00:09:19.540 all statically declared memory for you. 00:09:19.540 --> 00:09:23.100 It's only dynamically allocated memory-- only memory that you malloc 00:09:23.100 --> 00:09:24.970 are things that you should free. 00:09:24.970 --> 00:09:28.960 And then make sure not to free the same block of memory more than once 00:09:28.960 --> 00:09:31.417 because that can create the problem of a double free 00:09:31.417 --> 00:09:33.250 and you have sort of an inverse memory leak, 00:09:33.250 --> 00:09:36.374 like a memory flow or something, where you tricked the system into thinking 00:09:36.374 --> 00:09:38.110 that you have more memory than you do. 00:09:38.110 --> 00:09:40.443 It's not the kind of thing that you actually want to do. 00:09:40.443 --> 00:09:42.790 So remember, everything you malloc you should free. 00:09:42.790 --> 00:09:45.040 Only things that you malloc you should free. 00:09:45.040 --> 00:09:48.877 And don't free anything more than once. 00:09:48.877 --> 00:09:50.710 Let's just close this video by taking a look 00:09:50.710 --> 00:09:53.830 at a couple of lines of code and a visual example 00:09:53.830 --> 00:09:56.600 to show you exactly what's happening as we do it. 00:09:56.600 --> 00:09:59.290 So first, let's statically declare an integer called m. 00:09:59.290 --> 00:10:01.081 And so this would look something like this. 00:10:01.081 --> 00:10:04.030 I've colored the box green because in my head, sort of, 00:10:04.030 --> 00:10:06.230 integers are always in green boxes. 00:10:06.230 --> 00:10:09.400 And I've written the label m on the box. 00:10:09.400 --> 00:10:11.570 Then I'm going to say int star a. 00:10:11.570 --> 00:10:15.950 So here I'm statically declaring a pointer called a. 00:10:15.950 --> 00:10:20.660 So recall that I like to think of it's an int star, so it's int-like, 00:10:20.660 --> 00:10:21.660 so it will be green. 00:10:21.660 --> 00:10:22.610 It's a green-ish box. 00:10:22.610 --> 00:10:24.710 It's not a green box because that's for ints. 00:10:24.710 --> 00:10:26.420 But int stars are sort of green-ish. 00:10:26.420 --> 00:10:27.410 They refer to ints. 00:10:27.410 --> 00:10:30.570 So this is another box and this one is called a. 00:10:30.570 --> 00:10:37.050 Then I can say int star b equals malloc sizeof int. 00:10:37.050 --> 00:10:38.370 So what's going to happen here? 00:10:38.370 --> 00:10:41.244 Well, I'm going to have something called b that I'm giving a name to. 00:10:41.244 --> 00:10:43.460 So that's going to be sort of a light greenish box. 00:10:43.460 --> 00:10:47.480 And I'm asking malloc to dynamically give me one int's worth of space. 00:10:47.480 --> 00:10:51.020 And so what actually happened sort of visually is this. 00:10:51.020 --> 00:10:54.230 Notice that the actual integer I didn't give a name to. 00:10:54.230 --> 00:10:55.910 I don't have a name for it. 00:10:55.910 --> 00:10:57.830 It's one way typically that I know I don't 00:10:57.830 --> 00:10:59.430 have a statically declared integer. 00:10:59.430 --> 00:11:02.150 The only way that I can refer to that green box 00:11:02.150 --> 00:11:05.370 is by dereferencing the pointer called b. 00:11:05.370 --> 00:11:07.940 So b has a name, and that's statically declared. 00:11:07.940 --> 00:11:11.510 But I dereference b in order to get to this dynamically allocated memory. 00:11:11.510 --> 00:11:12.810 And of course, I'm not going to do this here. 00:11:12.810 --> 00:11:14.601 But the first thing I should do immediately 00:11:14.601 --> 00:11:17.150 after this is check to make sure that b is not null. 00:11:17.150 --> 00:11:19.100 If b is null, something has gone wrong and I 00:11:19.100 --> 00:11:21.830 need to stop my program immediately. 00:11:21.830 --> 00:11:25.020 Next, I can say something like this-- a equals ampersand m. 00:11:25.020 --> 00:11:27.200 If you recall from our video on pointers, 00:11:27.200 --> 00:11:29.560 basically this just means a points to m. 00:11:29.560 --> 00:11:33.080 So that just creates this arrow here. 00:11:33.080 --> 00:11:35.594 Next up, let's say a equals b. 00:11:35.594 --> 00:11:37.510 Before I show you what's going to happen here, 00:11:37.510 --> 00:11:39.770 can you try and guess a little bit about what it's going to be? 00:11:39.770 --> 00:11:40.895 Take a look at the diagram. 00:11:40.895 --> 00:11:43.160 Think about how relationships might change. 00:11:43.160 --> 00:11:47.850 If I say a equals b, what am I saying? 00:11:47.850 --> 00:11:51.890 What I'm saying is that a and b are now going to point to the same location, 00:11:51.890 --> 00:11:55.100 in particular, a is going to a point where b currently points. 00:11:55.100 --> 00:11:57.410 And so instead of pointing to m, a is now 00:11:57.410 --> 00:12:00.740 going to point over here to this dynamically allocated 00:12:00.740 --> 00:12:02.699 block that I can currently only reference-- now 00:12:02.699 --> 00:12:04.073 I can reference it multiple ways. 00:12:04.073 --> 00:12:05.570 Now I could say star a or star b. 00:12:05.570 --> 00:12:08.690 I can reference it either way because both of those same statically 00:12:08.690 --> 00:12:11.660 declared variables point to the same location. 00:12:11.660 --> 00:12:13.077 I can then say m equals 10. 00:12:13.077 --> 00:12:15.410 That's not a problem because 10 was statically declared. 00:12:15.410 --> 00:12:16.951 It's a box that I know about already. 00:12:16.951 --> 00:12:17.790 It's got a name. 00:12:17.790 --> 00:12:19.640 So when I say m equals 10, I'm just saying 00:12:19.640 --> 00:12:23.900 put 10 into this green box called m. 00:12:23.900 --> 00:12:27.046 Star b equals m plus 2. 00:12:27.046 --> 00:12:28.170 It's a little weird, right? 00:12:28.170 --> 00:12:29.270 But what's m plus 2? 00:12:29.270 --> 00:12:31.910 Well, m is 10, so 10 plus 2 is 12. 00:12:31.910 --> 00:12:34.040 And star b equals 12. 00:12:34.040 --> 00:12:36.950 When I say a star b, I'm dereferencing b. 00:12:36.950 --> 00:12:40.610 So I'm going to travel along the arrow to where b points. 00:12:40.610 --> 00:12:44.570 And I'm going to put 12 in that location. 00:12:44.570 --> 00:12:45.920 OK? 00:12:45.920 --> 00:12:48.510 Next up I'm going to free b. 00:12:48.510 --> 00:12:51.650 So remember what happens with free is we are telling the system we're 00:12:51.650 --> 00:12:53.450 no longer working with this. 00:12:53.450 --> 00:12:54.560 We're done. 00:12:54.560 --> 00:12:57.630 You can take these four bytes back, or whatever the size of it is. 00:12:57.630 --> 00:12:59.047 This one happens to be four bytes. 00:12:59.047 --> 00:13:00.880 You can take it back and use it for whatever 00:13:00.880 --> 00:13:02.420 you want in some other program. 00:13:02.420 --> 00:13:05.930 So when I free b, this memory basically goes away. 00:13:05.930 --> 00:13:11.044 a and b still point to where it used to be, but I no longer have access to it. 00:13:11.044 --> 00:13:13.460 If I try and touch it, the system might get upset with me. 00:13:13.460 --> 00:13:15.084 So for example, if I try and say this-- 00:13:15.084 --> 00:13:18.030 star a equals 11-- 00:13:18.030 --> 00:13:19.760 what's going to happen? 00:13:19.760 --> 00:13:21.447 Unpredictable behavior. 00:13:21.447 --> 00:13:22.030 We don't know. 00:13:22.030 --> 00:13:24.080 We might get a segmentation fault because we're 00:13:24.080 --> 00:13:26.400 touching memory that we're no longer-- 00:13:26.400 --> 00:13:28.782 we don't have write privileges to anymore. 00:13:28.782 --> 00:13:31.490 You might get away with it, depends on where that memory happened 00:13:31.490 --> 00:13:32.900 to live on the system. 00:13:32.900 --> 00:13:33.860 But it's unpredictable. 00:13:33.860 --> 00:13:36.440 So once you free memory, remember, you're telling the system, 00:13:36.440 --> 00:13:37.950 I don't need it anymore. 00:13:37.950 --> 00:13:42.246 So if you then try and use it, some strange things might result. 00:13:42.246 --> 00:13:44.120 Dynamic memory allocation is a little strange 00:13:44.120 --> 00:13:46.995 to get used to because we're so used this idea of creating a variable 00:13:46.995 --> 00:13:49.850 and assigning it a value and just manipulating it in that way 00:13:49.850 --> 00:13:52.640 that using pointers to sort of control where memory is 00:13:52.640 --> 00:13:56.460 and change it indirectly through pointers can be a bit strange. 00:13:56.460 --> 00:13:58.420 But just keep practicing with it. 00:13:58.420 --> 00:14:01.354 Internalize those rules about how to malloc and free successfully 00:14:01.354 --> 00:14:04.270 to make sure that you don't create memory leaks or anything like that. 00:14:04.270 --> 00:14:06.710 And you should be off to a good start. 00:14:06.710 --> 00:14:07.750 I'm Doug Lloyd. 00:14:07.750 --> 00:14:09.730 This is CS50.