 Welcome back. In the last segment, we discussed the basic primitives for dealing with the heap memory and we used them to solve a particular problem. Now we are going to discuss the issues in using the heap memory and what kinds of pitfalls there are. So, on the face of it, it seems and I guess it is true that the allocation and deallocation is syntactically quite simple. There are sort of simple commands which allow you to allocate and deallocate. Experience however shows that managing heap memory is tricky and lots of errors are made in the management of heap memory. So, these range from some very obvious ones to less obvious ones. Say for example, you may forget to deallocate or delete memory. What does that do? So you allocate a lot of memory. You do not delete it and then if you yourself want more memory, then there is nothing left in the heap. So, although you have some memory which you are not using and which you have not realized that you are not using, since you did not return it to the heap, the heap is unable to give you memory. So, that is sort of a basic problem. So as soon as you are done with the memory that you need it, you should return it back so that you can get it later on when you actually want it. Another problem is the so-called dangling reference problem. This happens if you refer to memory that has been deallocated. So, you got some memory, you are using it, you returned it and you are still referring to it. So, because you returned it, it might have been given to some other request and therefore you might be destroying the data which or you might be reading data which was not really the data that you thought was present in that location and you can also do something called a memory leak which is that you destroy the only pointer to the memory allocated on the heap before it is deallocated, before it is explicitly deallocated. So, we will talk about all these three in some detail. So, let us take an example. Suppose I have n star iptr, so iptr is a variable which contains which is expected to contain pointers to integers. So, I make it point to a new integer, I make it point to a space allocated on the heap. I store 5 into that space, then I delete that, then I write some code which could be a long piece of code but let us say it does not involve iptr and after that I again store 10 into that address by dereferencing iptr. Now this is not correct. So you did have, iptr did have a memory location which was given from the heap but now, so it was given here but you returned it over here and you did not acquire it again and place it into iptr. So therefore the location that you are pointing to is not really what you think it is. It is not your location and so you should really not be using it. So this reference iptr points to memory that has been returned and it should not be used. So therefore it is called a dangling reference and it is wrong to dereference a dangling reference as has happened over here. So let us talk about memory leaks. So again we have this iptr which is a variable for storing addresses of integers. So we acquire memory and get its pointer into, get its address into iptr and immediately we acquire more memory and get that address also into iptr. Now clearly this is wrong. So the memory allocated in statement 1 its address was stored, say let us call it a was stored in iptr but in statement 2 this a got overwritten. So now the memory allocated address a cannot be used by the program because we have, we do not have any address, we do not have its address. On the other hand we did not delete that memory before destroying that address and so the heap allocation functions, the heap manager thinks that address has been given to us. So now that piece of memory has become useless because it does not, we cannot use it and the heap manager cannot use it. Such memory is said to have leaked out of our system and obviously you do not want such leaks. Here is another way a leak can happen. So I have a block inside which I have a variable declared iptr, it is again of type in star. So again I allocate an integer and get its address into iptr. Let us say the block ends exactly at this point. What happens now? So when the control exits from the block all the variables which were declared in the block are destroyed. So after the control executes this and comes out there is no iptr. So that means there are the contents of iptr are gone. So I had written down the address on some piece of paper and that paper is no longer there. So I do not know that address. That is exactly what has happened. So iptr is destroyed and so nobody can use the memory allocated in statement one. So we cannot use it because we do not know the address and the heap manager thinks that it is given to us. So therefore the heap manager cannot use it either. So the memory at address A has become unusable. So here is a simple strategy for preventing memory leaks. So what is the strategy? So suppose a certain pointer variable ptr is the only variable that contains the address of a variable allocated on the heap. So clearly we must not store anything into ptr and destroy its contents because that would exactly be a memory leak. If ptr is about to go out of scope say because control exits the block in which ptr is defined we must execute delete ptr. So these are two rules that we have to keep in mind. So if we keep in mind these two rules then we will be sure that there are no memory leaks. Likewise there is a simple strategy for preventing dangling references. So here is sort of a reason why we get dangling references. So we saw one but this is sort of a more general thing. So let us say there are two or more pointers let us say just say two for example and let us say they are aptr and vptr which point to the same variable on the heap and we execute delete aptr and we do not realize that vptr is also pointing to that same memory and therefore we should not be dereferencing vptr either. So but suppose we do dereference vptr and we get to that memory then that is a dangling reference which we have dereferenced. And of course we could have dereferenced aptr itself so both are not good. So what should we do? A simple way to avoid this is to ensure that at all times each variable in the heap will be pointed to only by one ptr. So there is this case is not going to arise that I deleted the memory using this pointer but I did not realize that some other pointer was also pointing to the same memory. And of course if I deleted the memory using this particular pointer I should also make sure that I do not use this particular pointer and dereference it subsequently. That is relatively easier to implement of course you can forget but at least that seems easier than saying oh there could be some 5 pointers to the same location of the heap and do I really know which those 5 pointers are. So that is a little bit tricky. So to avoid that situation we are going to say that at any time each variable on the heap will be pointed only by one ptr. And this is not the only possible strategy more complicated and more efficient and in some ways better strategies are possible but this is a fairly good reasonable strategy. So what have we discussed? So we have talked about memory leaks and dangling pointers and we said that to avoid these we should ensure that each variable allocated on the heap is pointed to by exactly one pointer at any time. If a ptr points to a heap variable then before executing a ptr equal to something changing its value we execute delete aptr. If aptr points to a heap variable and if control is about to exit the block in which aptr is defined then we execute delete aptr as well. So this is the strategy and this strategy requires us to remember things but fortunately we can automate it so that we do not really have to remember all of these things. So at some point we have to remember and we have to put them into code such that the code will be automatically executed and how that happens we will talk about in the next segment but before that we will take a quick break.