 Welcome back, in the last segment we started off by defining a problem that we wanted to solve which is how to efficiently use memory for storing entities with varying sizes. And we said that there is something called heap memory which can be used to implement solutions for such problems. In this segment we are going to use this heap memory, we are going to see how to use this heap memory. Okay, so let us take an example, we want to store a book object on the heap. So here is our book object, so it is a class book, car title and there is price. Maybe I should call it struct because I am using the internals, the members directly, so perhaps I should have called it a struct, but anyway. So I can declare a BPTR to be a pointer to a book object. So right now BPTR is not, does not contain a value, I am just defining that variable. Now here I am assigning a value to BPTR and this is a new statement. So this says BPTR equal to new book. New is actually an operator and this operator asks for heap memory. The syntax in general is going to be new followed by the name of a type. And what this causes is that memory for storing one variable of type t is allocated on the heap, is reserved on the heap. And this statement new t or new book returns the address of the allocated memory. So the address of that allocated memory comes back to the program and then that address gets stored in BPTR. So BPTR now has a pointer or BPTR contains the address of some location in the heap memory which has been given in response to this request. So now we can use that location. So we can write BPTR.arrow price because BPTR is a pointer. So we go to that variable and we look at the price member from it. And in this way we can keep using the memory as much as we want. We can change the price, we can change the title, we can do whatever with it. At some point we will discover or we will decide that look I do not need this memory any longer. So in that case we should return the memory back. We should tell the heap or the heap manager so to say that look I was using this memory but now I do not need it. So take it back and maybe give it to me later if I ask for it again. So that is done by this command delete BPTR. So that returns that memory back. New and delete are reserved words and they are also operators. Well a lot happens behind the scenes for view and delete. So there is some bookkeeping which keeps track of which part of the heap is currently in use. And as a result of this bookkeeping you are guaranteed that in response to a new request you will get memory that is not currently allocated to another request. Of course if the heap is full then you will run out of memory and your program will abort but if it is not full then you will get that memory. And the same region of memory can be allocated to two requests but only if the first request releases it using the delete before the second request is made. So at the same time the same memory cannot be in use due to two requests. So here is an example showing how the heap memory functions and how it is different from the standard activation frame memory. So in this program let us look at main. So main starts off with creating a variable Q which is a pointer to end which is of type int star and Q is being assigned the result of calling g. So g is called and notice that g is actually returning a pointer to end, int star g. So int star is the return type and g is returning a pointer to end. So what happens inside g? Well first a local variable or a p is created of type int star. So this is in the activation frame of g. Then we execute our new statement p equals new end. So what does this do? Well it places an address in the heap so it causes a location in the heap to be allocated and that address is placed in p. So p is now pointing to some location in heap memory which has been given for it. Then we say star p equal to 5. So what does this do? Well star p takes you to the location in heap memory and you place a 5 over there. So 5 is stored in the location in the heap memory which was given to us and now we are returning p. So what does return p mean? Well whatever the value of p is is return. But what is the value of p? So the value of p is the heap memory address. So this heap memory address is returned and this goes and takes the place effectively of this call and it sits in this queue. So that address goes and sits in queue. And now when we print star q what is happening? So q at this point contains an address in the heap memory which was allocated over here. So star q is pointing to that same address but into which we had stored a 5 over here and therefore if you print star q it will print 5. So at this point we have discovered that we do not need q any longer or we have decided that we do not need q any longer and therefore we are going to delete q. So notice that there is something unusual going on from the point of view of what you have known so far which is that some memory got allocated over here and it is stayed across this function call boundary and then it was used in the main program and then it was deleted in the main program. So this is clearly very very different from the way the memory allocation happens on the activation frames. You can allocate arrays on the heap and so again let us say cptr is a pointer to characters. Now I can say cptr equals mu char 10. So this will give me an array of length 10 and array of char and now I can start accessing the array as usual because after all the name of the array is an address, address of the starting and cptr also is an address, address of the starting point of that array. So I can get the usual variable cptr0, cptr9. So the array elements I can just access in this manner. After I am done with the heap I can write delete square bracket cptr. So this causes the allocated array to be deleted. So note that it is not just plain delete but it is delete square bracket. So now we are pretty much in control of the situation. So our problem was storing many names and now we are able to do so. So let us see how. So let us say we want to store 100 names and so I am going to define an array of pointers, pointers to char. So I have an array of pointers and initially I have not put anything in it. So let me draw it pictorially. So this is my array names and let us say this is the 0th element, first element all the way till the 99th element. So what happens next? So I am going to go over all the elements of this array and I am going to have an iteration corresponding to all the elements of the array and in the iteration I am going to read in something into the buffer. I am going to read in the names into the buffer. Then I am going to calculate the length. So say on the side over here I have this buffer into which I read in something and as usual there will be a null after that and now I am going to call a function length which is supposed to return the number of characters till the null. So in this case it should return 3. So this function we have discussed earlier or we have discussed something like this earlier and this function is also discussed in the book but it is a very simple function. So you should be able to write it very, very easily. So it just returns how many characters there are until the null and L is set equal to that length plus 1. So what is the idea here? So we want to move, we want to allocate an array of just the right size. So L is going to be just the right size because in that array we want to store the name that we just read but we want to append a null character to it. So the plus 1 is so that we can append a null and now we are going to allocate space. So names of i, so in general let us start from 0. So this is a pointer, so this is of type char star. So it is going to be a pointer to a character. So we are going to do in this statement over here we are going to do names of i or say names of 0 in the 0th iteration equal to new char L. So there is some heap somewhere over here and from that heap I am going to get an allocation of an array of say in this case if L is 4 because there are 3 characters plus 1 then I am going to get an allocation of size 4 and the address of this is going to be put in over here. So typically we do this, draw this by making an arrow saying that whatever is here is pointing to this. So it really says that contained over here is the address of this location. So we have just allocated space for storing this in the heap and we have a pointer to that from our names array. Now we simply are going to copy. So we are going to copy from the buffer, so this is our buffer. So from this we copy into this. So whatever these 3 letters were followed by a null is going to get copied over here. So this is our buffer and this is names of 0 0, names of 0 1, names of 0 2, names of 0 3. So what has happened over here is that we read a name, we allocated space for it plus 1 so that we want to pad it with a null and then we copied that into the name into the newly allocated space and this we are going to do for all the 100 names that we want to work with. So that is it, so that is the program. And so I guess it is a good idea to see what the final result is going to look like. So this names array, so this is going to be present in the activation frame. So if this is the main program then this array is going to be present in the activation frame of the main program and this however is present in the heap memory and similarly from here another array, there will be a pointer to another array, maybe this time the name is long. From here there will be another pointer to another array and so on. So from each element of this names array there will be pointers to arrays in the heap memory. So all of this part is stored in the heap memory. Now in this case I have not shown you the deletion but of course you can write a loop and again once you are done you can delete all the variables and give back the memory to the heap. So this is the solution that we were asking for and we have just about used the memory that we needed. Well we used one null character extra for each name. So that is very minimal. And what is in the activation frame of main and what is on the heap we already discussed that. So in the heap memory all the arrays storing the names are there and in the activation frame the array names itself which contains pointers is in the activation frame. So what have we discussed in this segment? So in this segment we talked about how to use the heap memory. In particular we talked about the new and delete operators and then we talked about a solution to the problem with which we started the lecture and we showed that using new and delete we can in fact store all the names in a reasonably small amount of space and then we can get to those names quite easily as well. Now it turns out that while this solution is acceptable it is actually quite tricky to use the new and delete operators. And so we need to really evolve something more than just these two operators. We need to have some scheme, some policy for using new and delete and there are some difficulties in it, some pitfalls and in the next lecture we are going to talk about these pitfalls. But before that let us take a short break.