03.01.2013 Views

Chapter 1

Chapter 1

Chapter 1

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

this line yourself, and then rerun the scenario above. Select New 1, and then exit. The<br />

destructor should ensure heap balance, and the program will exit cleanly.<br />

To summarize, you should only delete objects that you own – that is, objects with which you<br />

have a has-a relationship.<br />

Once you've added delete iObject1 to CExampleAppUi's destructor, rebuild<br />

memorymagic and start it again. Select New 1 twice, and then exit. You'll get another panic.<br />

The reason for this should be obvious. The second time through, we simply created a<br />

second CX, stored its address in iObject1, and forgot the address of the CX object we<br />

allocated previously. There was no way for the destructor – or any other part of the C++<br />

system – to find this object, so it couldn't be deleted.<br />

We could have solved this by coding:<br />

case EMagicCmdNew1:<br />

delete iObject1;<br />

iObject1 = new CX;<br />

iEikonEnv->InfoMsg(_L("New 1"));<br />

break;<br />

Here, we're taking advantage of the zero-checking service that C++ provides as part of<br />

delete. If the object has already been allocated, we delete it and allocate it again. If it<br />

hasn't yet been allocated, the delete statement will do nothing.<br />

If you build this new line into memorymagic, you should find that it exits cleanly no matter<br />

how many times you select New 1.<br />

There is one other technique that can help us to avoid allocating twice. We can ensure that<br />

this does not happen by adding an ASSERT before allocating member variables, like this:<br />

ASSERT(iObject1 == NULL);<br />

iObject1 = new CX;<br />

Don't allocate twice<br />

If double allocation is a serious crime, then deleting twice is a capital offense. If you allocate<br />

something twice, the result is a heap cell that doesn't get destroyed, which gets picked up<br />

eventually by a __UHEAP_MARKEND. If you delete something twice, the effects can be more<br />

subtle.memorymagic can demonstrate this effect too. Select New 1 from the menu, and<br />

then select Delete 1 twice. In this case, I found that the application panics immediately, but<br />

in other situations I haven't always been so lucky: double deletion doesn't always cause an<br />

immediate crash, and sometimes it leaves side effects that only surface a long time after the<br />

real problem – the double delete – occurred. As a result, double deletes are very hard to<br />

debug.<br />

On the other hand, double deletes are easy to avoid – just follow this little discipline:<br />

Important<br />

C++ delete does not set the pointer to zero. If you delete any member<br />

object from outside its class's destructor, you must set the member<br />

pointer to NULL.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!