1 /*---------------------------------------------------------------------------*
2   Project:  How to set up new/delete operators for C++
3   File:     cppsetupdemo.cpp
4 
5   Copyright 1998, 1999 Nintendo.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Log: cppsetupdemo.cpp,v $
14   Revision 1.3  2007/07/12 10:17:52  hiratsu
15   delete[] was missing.  Fixed.
16 
17   Revision 1.2  2006/02/20 04:13:11  mitu
18   changed include path from dolphin/ to revolution/.
19 
20   Revision 1.1  2006/01/13 11:24:13  hiratsu
21   Initial check in.
22 
23 
24     4     6/11/01 7:55p Tian
25     Integrated SN changes
26 
27     3     3/16/01 12:04p Tian
28     Comments fix
29 
30     2     9/29/00 5:27p Tian
31     OS now supports pre-main new.
32 
33     1     6/22/00 7:24p Tian
34     Initial checkin.
35   $NoKeywords: $
36  *---------------------------------------------------------------------------*/
37 
38 /*---------------------------------------------------------------------------*
39   This demo shows how to override the standard new/delete operators with the
40   Dolphin OS memory allocator.  Note the following important caveats:
41 
42   - the standard Metrowerks new/delete operators are NOT supported,
43   and will cause a DSI exception if you attempt to use them.
44 
45   - this demo works because our new/delete operators occur earlier in
46   the link order than the Metrowerks Standard Libraries.  If the MSL
47   libraries occur earlier in the link order than your definition of
48   new/delete, then the MSL new/delete will be used throughout your
49   code.
50 
51   This demo does show how to use static global constructors.  The trick is
52   to initialize the heap in the first invocation of new().  The flag
53   /IsHeapInitialized/ is used in this example to indicate whether or not
54   the heap has been initialized.
55  *---------------------------------------------------------------------------*/
56 
57 #include <revolution.h>
58 #include <stddef.h>
59 /*---------------------------------------------------------------------------*
60   Override new and delete
61  *---------------------------------------------------------------------------*/
62 
63 #define HEAP_ID 0
64 
65 static BOOL IsHeapInitialized = FALSE;
66 
67 
68 /*---------------------------------------------------------------------------*
69   Name:         CPPInit
70 
71   Description:  Initializes the Dolphin OS memory allocator and ensures that
72                 new and delete will work properly.
73 
74   Arguments:    None.
75 
76   Returns:      None.
77  *---------------------------------------------------------------------------*/
CPPInit()78 static void CPPInit()
79 {
80     void*    arenaLo;
81     void*    arenaHi;
82 
83     if (IsHeapInitialized)
84     {
85         return;
86     }
87 
88 
89     arenaLo = OSGetArenaLo();
90     arenaHi = OSGetArenaHi();
91 
92     // Create a heap
93     // OSInitAlloc should only ever be invoked once.
94     arenaLo = OSInitAlloc(arenaLo, arenaHi, 1); // 1 heap
95     OSSetArenaLo(arenaLo);
96 
97     // Ensure boundaries are 32B aligned
98     arenaLo = (void*)OSRoundUp32B(arenaLo);
99     arenaHi = (void*)OSRoundDown32B(arenaHi);
100 
101     // The boundaries given to OSCreateHeap should be 32B aligned
102     OSSetCurrentHeap(OSCreateHeap(arenaLo, arenaHi));
103     // From here on out, OSAlloc and OSFree behave like malloc and free
104     // respectively
105     OSSetArenaLo(arenaLo=arenaHi);
106     IsHeapInitialized = TRUE;
107 
108 }
109 
operator new(size_t blocksize)110 inline void* operator new       ( size_t blocksize )
111 {
112     if (!IsHeapInitialized)
113     {
114         CPPInit();
115     }
116     return OSAllocFromHeap(HEAP_ID, blocksize);
117 }
118 
operator new[](size_t blocksize)119 inline void* operator new[]     ( size_t blocksize )
120 {
121     if (!IsHeapInitialized)
122     {
123         CPPInit();
124     }
125     return OSAllocFromHeap(HEAP_ID, blocksize);
126 }
127 
operator delete(void * block)128 inline void operator delete     ( void* block )
129 {
130     OSFreeToHeap(HEAP_ID, block);
131 }
132 
operator delete[](void * block)133 inline void operator delete[]   ( void* block )
134 {
135     OSFreeToHeap(HEAP_ID, block);
136 }
137 
138 
139 
140 /*---------------------------------------------------------------------------*
141   Trivial C++ code to test new and delete
142  *---------------------------------------------------------------------------*/
143 
144 
145 class Foo
146 {
147   private:
148     u32 a;
149     u32 b;
150     char* array;
151 
152   public:
153     Foo();
154     ~Foo();
155 
printA(void)156     void printA(void)
157     {
158         OSReport("a = %d\n", a);
159     }
160     void printB(void);
161 };
162 
163 
164 /*---------------------------------------------------------------------------*
165   Name:         Foo::Foo
166 
167   Description:  Constructor for class Foo.  Simply initialize private
168                 members.
169 
170   Arguments:
171 
172   Returns:
173  *---------------------------------------------------------------------------*/
Foo()174 Foo::Foo()
175 {
176     a = 42;
177     b = 24;
178 
179     array = new char[32];
180 }
181 
182 
183 /*---------------------------------------------------------------------------*
184   Name:         Foo::~Foo
185 
186   Description:  Destructor for class Foo.  Performs an OSReport so we know
187                 it got called properly.
188 
189   Arguments:
190 
191   Returns:
192  *---------------------------------------------------------------------------*/
~Foo()193 Foo::~Foo()
194 {
195     OSReport("Foo destructor\n");
196     delete [] array;
197 }
198 
199 
200 
201 /*---------------------------------------------------------------------------*
202   Name:         Foo::printB
203 
204   Description:  function to print out b member
205 
206   Arguments:
207 
208   Returns:
209  *---------------------------------------------------------------------------*/
printB()210 void Foo::printB()
211 {
212     OSReport("b = %d\n", b);
213 }
214 static Foo StaticFoo;
215 
216 
main()217 int main()
218 {
219     Foo * foo;
220 
221     OSInit();
222     CPPInit();
223 
224     foo = new Foo;
225 
226     foo->printA();
227     foo->printB();
228     StaticFoo.printA();
229 
230     delete foo;
231 	return 0;
232 }
233