examples/Base/MemMan/Cleanup/MemLeakOOM/MemLeakOOM.cpp

00001 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
00002 // All rights reserved.
00003 // This component and the accompanying materials are made available
00004 // under the terms of "Eclipse Public License v1.0"
00005 // which accompanies this distribution, and is available
00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
00007 //
00008 // Initial Contributors:
00009 // Nokia Corporation - initial contribution.
00010 //
00011 // Contributors:
00012 //
00013 // Description:
00014 // NOTE: the structure of this example is different to standard E32 examples
00015 //
00016 
00017 
00018 #include <e32cons.h>
00019 
00020   // All messages written to this
00021 LOCAL_D CConsoleBase* console;
00022   
00023   // Function prototypes
00024 LOCAL_C void doExampleL();      
00025 LOCAL_C void callExampleL();
00026 
00027 
00029 //
00030 // -----> CSimple (definition)
00031 //
00033 class CSimple : public CBase
00034         {
00035 public :
00036         static CSimple* NewL(TInt aVal);
00037         static CSimple* NewLC(TInt aVal);
00038         void   Display();
00039 protected: 
00040         CSimple(TInt aVal);
00041 public: 
00042         TInt   iVal;
00043         };
00044 
00045 
00047 //
00048 // -----> CCompound (definition)
00049 //
00051 class CCompound : public CBase
00052         {
00053 public :
00054         virtual  ~CCompound();
00055         void     Display();
00056         static   CCompound* NewL(TInt aRoot,TInt aChild);
00057         static   CCompound* NewLC(TInt aRoot,TInt aChild);
00058 private:
00059         TInt     iRoot;
00060         CSimple* iChild;
00061 protected:
00062         CCompound(TInt aRoot,TInt aChild);
00063     };
00064 
00066 //
00067 // -----> CCompound (implementation)
00068 //
00070 
00071                                 // A one stage construction technique
00072                     // using the C++ constructor mechanism
00073 CCompound* CCompound::NewL(TInt aRoot,TInt aChild)
00074         {                       
00075           // Allocate and construct object; leave if allocation fails
00076         CCompound* self=new (ELeave) CCompound(aRoot,aChild);
00077         return self;
00078         }
00079 
00080 CCompound* CCompound::NewLC(TInt aRoot,TInt aChild) 
00081         {
00082         CCompound* self=NewL(aRoot,aChild);     
00083         CleanupStack::PushL(self);
00084         return self;
00085         }
00086 
00087 CCompound::CCompound(TInt aRoot,TInt aChild)
00088         {
00089         iRoot = aRoot;
00090         iChild = CSimple::NewL(aChild);         
00091                         // problem:if this line leaves, memory 
00092                         // leak (orphan) will result
00093         iChild->iVal = aChild;
00094         }
00095                                 
00096 void CCompound::Display() 
00097         {
00098           // Display class member data on the console
00099         _LIT(KFormat4,"Root=%d. Child=%d.\n");
00100         console->Printf(KFormat4,iRoot,iChild->iVal);
00101         }
00102                                 
00103 CCompound::~CCompound() 
00104         {
00105         _LIT(KMsgDestCCompound,"Destructing CCompound\n");
00106         console->Printf(KMsgDestCCompound);
00107         delete iChild;
00108         }
00109 
00110 
00112 //
00113 // -----> CSimple (implementation)
00114 //
00116 CSimple* CSimple::NewL(TInt aVal) 
00117         {
00118           // NB The NewL function uses the C++ constructor mechanism.
00119         CSimple* self=new (ELeave) CSimple(aVal);
00120         return self;
00121         }
00122 
00123                                 
00124 CSimple* CSimple::NewLC(TInt aVal)
00125         {
00126           // NewLC is enriched with a push to the cleanup stack
00127         CSimple* self=NewL(aVal);       
00128         CleanupStack::PushL(self);
00129         return self;
00130         }
00131 
00132                                 
00133 void CSimple::Display() 
00134         {
00135           // Display class data member on the console.
00136         _LIT(KFormat1,"Value=%d.\n");
00137         console->Printf(KFormat1,iVal);
00138         }
00139  
00140 CSimple::CSimple(TInt aVal) 
00141         : iVal(aVal)
00142         {}
00143 
00144 
00146 //
00147 // Main function called by E32
00148 //
00150 GLDEF_C TInt E32Main()
00151     {
00152           // Get cleanup stack
00153         CTrapCleanup* cleanup=CTrapCleanup::New();
00154 
00155           // Some more initialization, then do the example
00156         TRAPD(error,callExampleL());
00157           
00158           // callExampleL() should never leave.
00159         _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
00160         __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));
00161 
00162           // destroy the cleanup stack
00163         delete cleanup;
00164         
00165           // return
00166         return 0;
00167     }
00168 
00169 
00171 //
00172 //
00173 //
00175 LOCAL_C void callExampleL() 
00176     {
00177           // Initialize and call the example code under cleanup stack.
00178         _LIT(KMsgExampleCode,"Symbian platform Example Code");
00179         console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
00180           // Put console onto the cleanup stack.
00181         CleanupStack::PushL(console);
00182 
00183           // Mark for alloc heaven tool
00184         __UHEAP_MARK;                      
00185 
00186           // Perform the example function under the protection of a 
00187           // TRAP harness.
00188         TRAPD(error,doExampleL());
00189         
00190           // Test the example for alloc heaven
00191           __UHEAP_MARKEND;
00192 
00193           // 
00194         _LIT(KMsgOK,"ok");
00195         _LIT(KFormat2,"Overall example Trap Harness failed: leave code=%d");
00196         if (error)
00197                 console->Printf(KFormat2, error);
00198         else
00199                 console->Printf(KMsgOK);
00200           
00201           // Continue
00202         _LIT(KMsgPressAnyKey," [press any key]");
00203         console->Printf(KMsgPressAnyKey);
00204         console->Getch();
00205 
00206           // Remove the console object from the cleanupstack
00207           // and destroy it. 
00208         CleanupStack::PopAndDestroy();
00209     }
00210 
00211 
00213 //
00214 // Do the example
00215 //
00216 // Example to check robustness of class on OOM and attempt to provoke
00217 // memory leaks (orphans).
00219 void doExampleL()
00220         {
00221         #if defined(_DEBUG)  //only ever used in debug mode
00222         TInt failValue = 5;
00223         #endif
00224 
00225           // Startup the alloc failure tool to fail in the third cycle.
00226           // To test for alloc heaven:
00227           //
00228           // An even value for 'failValue' should provoke memory leak,
00229           // an odd value should not.
00230         __UHEAP_SETFAIL(RHeap::EDeterministic,failValue);
00231         
00232         for(TInt ii=1;ii<4;ii++)
00233                 {
00234                   // Display status information
00235                 _LIT(KFormat3,"Cycle %d.\n");
00236                 console->Printf(KFormat3,ii);
00237                   // Create new instance 
00238                 CCompound* myCompoundExample = CCompound::NewL(1,2);
00239                   // Display the instance
00240                 myCompoundExample->Display();
00241                   // Destroy the instance
00242                 delete myCompoundExample;
00243                 } 
00244         }
00245 
00246 

Generated by  doxygen 1.6.2