Previously, we *returned* addresses allocated on the heap to share values that needed to persist beyond the end of a function call. However, we may want to use the return value of a function for other purposes, or we may wish to alter a pointer in the calling functions. Whatever the reason, it's important to know how to use a parameter to store the address of dynamically allocated memory. Here, we have a C function that dynamically allocates an array of 3 integers on the heap and assigns values to those integers. The address of that block is assigned to a local variable arr. When the function returns, the data will still be allocated on the heap, so to continue using the data -- and to avoid a memory leak, we need to retain a copy of the heap address. In past videos, we returned the value of arr to the calling function and assigned it to a local variable there. This would mean making the return type of helper int * and adding the return statement. We return the value of variable arr. And here is the calling code from main. We assign the return value of our function to the local variable data. Another approach is to use a parameter to our helper function to store the address of the array on the heap. First, we change the return type, since we aren't going to use the return statement for the address of our malloc'ed space. Now, it's free for other uses, like signaling an error, although in this example, we simply won't return anything at all. The value we would like to get back to our calling program is the address of the array -- the value of arr. That's what we returned in our earlier version. And the type of arr is int *. Here's a common mistake. It would be a mistake to make the parameter int * -- but let's try it. And now let's call the function in main. What do you think we'll see when we run this code? If this had worked, we would have seen a 21, but we see a 0. Why Remember where this is allocated. arr is a local variable on the stack of the helper function. When we call helper, it gets the value of data. But when we modify arr, we're modifying a local variable, not the variable data from main. The visualizer highlights this. arr is being changed, but data is not -- and we want to change the pointer data. This means we need a parameter that allows us to change the pointer -- so our parameter should be of type int **. We'll pass the address of data, rather than the value in data. Then, when we allocate the space for the array, we're modifying our original pointer -- from the calling context, main -- rather than a local variable. Since we want the dereference to happen first, we put it in parenthesis. For convenience, so we don't have to dereference our parameter everywhere, we'll create a local variable that stores a reference to the array. Now, we get the value we expect. And using the visualizer, we can see that when we store the return value of malloc, it's being stored in data, rather than in a copy, as it was in our previous example. Now, let's look quickly at a common mistake. We put this line below the call to malloc. But what if we put it higher, above the malloc call? It avoids the awkward parenthesis and dereference. The types are all ok and the compiler has no objection. But when we run it, we encounter the same situation as before -- data isn't referring to our new array. Like before, we're creating a local variable, and that local variable gets the return value of malloc -- rather than data itself. We can still access the heap values correctly through arr -- after data has been updated -- but we need to make sure we set the value of data. Finally before we finish, let's free the memory we dynamically allocated. Where should the free statement go and what should be the parameter? We should free the memory as soon as we are finished using it. We can't free it before we finish using it, or we will have a dangling pointer. So it needs to go here in the main function, after the last use of the pointer. Variable 'data' holds the address returned from our malloc call, so this is the parameter we pass to free. In the next video we will look at allocating space for more complicated data-structures.