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

00001 /*
00002 Copyright (c) 2000-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003 
00004 Redistribution and use in source and binary forms, with or without
00005 modification, are permitted provided that the following conditions are met:
00006 
00007 * Redistributions of source code must retain the above copyright notice, this
00008   list of conditions and the following disclaimer.
00009 * Redistributions in binary form must reproduce the above copyright notice,
00010   this list of conditions and the following disclaimer in the documentation
00011   and/or other materials provided with the distribution.
00012 * Neither the name of Nokia Corporation nor the names of its contributors
00013   may be used to endorse or promote products derived from this software
00014   without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 
00027 Description:
00028 NOTE: the structure of this example is different to standard E32 examples  
00029 */
00030 
00031 
00032 
00033 #include <e32cons.h>
00034 
00035   // All messages written to this
00036 LOCAL_D CConsoleBase* console;
00037   
00038   // Function prototypes
00039 LOCAL_C void doExampleL();      
00040 LOCAL_C void callExampleL();
00041 
00042 
00044 //
00045 // -----> CSimple (definition)
00046 //
00048 class CSimple : public CBase
00049         {
00050 public :
00051         static CSimple* NewL(TInt aVal);
00052         static CSimple* NewLC(TInt aVal);
00053         void   Display();
00054 protected: 
00055         CSimple(TInt aVal);
00056 public: 
00057         TInt   iVal;
00058         };
00059 
00060 
00062 //
00063 // -----> CCompound (definition)
00064 //
00066 class CCompound : public CBase
00067         {
00068 public :
00069         virtual  ~CCompound();
00070         void     Display();
00071         static   CCompound* NewL(TInt aRoot,TInt aChild);
00072         static   CCompound* NewLC(TInt aRoot,TInt aChild);
00073 private:
00074         TInt     iRoot;
00075         CSimple* iChild;
00076 protected:
00077         CCompound(TInt aRoot,TInt aChild);
00078     };
00079 
00081 //
00082 // -----> CCompound (implementation)
00083 //
00085 
00086                                 // A one stage construction technique
00087                     // using the C++ constructor mechanism
00088 CCompound* CCompound::NewL(TInt aRoot,TInt aChild)
00089         {                       
00090           // Allocate and construct object; leave if allocation fails
00091         CCompound* self=new (ELeave) CCompound(aRoot,aChild);
00092         return self;
00093         }
00094 
00095 CCompound* CCompound::NewLC(TInt aRoot,TInt aChild) 
00096         {
00097         CCompound* self=NewL(aRoot,aChild);     
00098         CleanupStack::PushL(self);
00099         return self;
00100         }
00101 
00102 CCompound::CCompound(TInt aRoot,TInt aChild)
00103         {
00104         iRoot = aRoot;
00105         iChild = CSimple::NewL(aChild);         
00106                         // problem:if this line leaves, memory 
00107                         // leak (orphan) will result
00108         iChild->iVal = aChild;
00109         }
00110                                 
00111 void CCompound::Display() 
00112         {
00113           // Display class member data on the console
00114         _LIT(KFormat4,"Root=%d. Child=%d.\n");
00115         console->Printf(KFormat4,iRoot,iChild->iVal);
00116         }
00117                                 
00118 CCompound::~CCompound() 
00119         {
00120         _LIT(KMsgDestCCompound,"Destructing CCompound\n");
00121         console->Printf(KMsgDestCCompound);
00122         delete iChild;
00123         }
00124 
00125 
00127 //
00128 // -----> CSimple (implementation)
00129 //
00131 CSimple* CSimple::NewL(TInt aVal) 
00132         {
00133           // NB The NewL function uses the C++ constructor mechanism.
00134         CSimple* self=new (ELeave) CSimple(aVal);
00135         return self;
00136         }
00137 
00138                                 
00139 CSimple* CSimple::NewLC(TInt aVal)
00140         {
00141           // NewLC is enriched with a push to the cleanup stack
00142         CSimple* self=NewL(aVal);       
00143         CleanupStack::PushL(self);
00144         return self;
00145         }
00146 
00147                                 
00148 void CSimple::Display() 
00149         {
00150           // Display class data member on the console.
00151         _LIT(KFormat1,"Value=%d.\n");
00152         console->Printf(KFormat1,iVal);
00153         }
00154  
00155 CSimple::CSimple(TInt aVal) 
00156         : iVal(aVal)
00157         {}
00158 
00159 
00161 //
00162 // Main function called by E32
00163 //
00165 GLDEF_C TInt E32Main()
00166     {
00167           // Get cleanup stack
00168         CTrapCleanup* cleanup=CTrapCleanup::New();
00169 
00170           // Some more initialization, then do the example
00171         TRAPD(error,callExampleL());
00172           
00173           // callExampleL() should never leave.
00174         _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
00175         __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));
00176 
00177           // destroy the cleanup stack
00178         delete cleanup;
00179         
00180           // return
00181         return 0;
00182     }
00183 
00184 
00186 //
00187 //
00188 //
00190 LOCAL_C void callExampleL() 
00191     {
00192           // Initialize and call the example code under cleanup stack.
00193         _LIT(KMsgExampleCode,"Symbian platform Example Code");
00194         console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
00195           // Put console onto the cleanup stack.
00196         CleanupStack::PushL(console);
00197 
00198           // Mark for alloc heaven tool
00199         __UHEAP_MARK;                      
00200 
00201           // Perform the example function under the protection of a 
00202           // TRAP harness.
00203         TRAPD(error,doExampleL());
00204         
00205           // Test the example for alloc heaven
00206           __UHEAP_MARKEND;
00207 
00208           // 
00209         _LIT(KMsgOK,"ok");
00210         _LIT(KFormat2,"Overall example Trap Harness failed: leave code=%d");
00211         if (error)
00212                 console->Printf(KFormat2, error);
00213         else
00214                 console->Printf(KMsgOK);
00215           
00216           // Continue
00217         _LIT(KMsgPressAnyKey," [press any key]");
00218         console->Printf(KMsgPressAnyKey);
00219         console->Getch();
00220 
00221           // Remove the console object from the cleanupstack
00222           // and destroy it. 
00223         CleanupStack::PopAndDestroy();
00224     }
00225 
00226 
00228 //
00229 // Do the example
00230 //
00231 // Example to check robustness of class on OOM and attempt to provoke
00232 // memory leaks (orphans).
00234 void doExampleL()
00235         {
00236         #if defined(_DEBUG)  //only ever used in debug mode
00237         TInt failValue = 5;
00238         #endif
00239 
00240           // Startup the alloc failure tool to fail in the third cycle.
00241           // To test for alloc heaven:
00242           //
00243           // An even value for 'failValue' should provoke memory leak,
00244           // an odd value should not.
00245         __UHEAP_SETFAIL(RHeap::EDeterministic,failValue);
00246         
00247         for(TInt ii=1;ii<4;ii++)
00248                 {
00249                   // Display status information
00250                 _LIT(KFormat3,"Cycle %d.\n");
00251                 console->Printf(KFormat3,ii);
00252                   // Create new instance 
00253                 CCompound* myCompoundExample = CCompound::NewL(1,2);
00254                   // Display the instance
00255                 myCompoundExample->Display();
00256                   // Destroy the instance
00257                 delete myCompoundExample;
00258                 } 
00259         }
00260 
00261 

Generated by  doxygen 1.6.2