]> git.saurik.com Git - wxWidgets.git/blob - include/wx/memory.h
fixed mysterious mistakes
[wxWidgets.git] / include / wx / memory.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: memory.h
3 // Purpose: MDI classes
4 // Author: Arthur Seaton, Julian Smart
5 // Modified by:
6 // Created: 29/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Julian Smart
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef __MEMORYH__
13 #define __MEMORYH__
14
15 #ifdef __GNUG__
16 #pragma interface "memory.h"
17 #endif
18
19 #include "wx/defs.h"
20
21 /*
22 The macro which will be expanded to include the file and line number
23 info, or to be a straight call to the new operator.
24 */
25
26 #if (WXDEBUG && USE_MEMORY_TRACING) || USE_DEBUG_CONTEXT
27
28 #include <stddef.h>
29
30 #if USE_IOSTREAMH
31 #include <iostream.h>
32 #else
33 #include <iostream>
34 #endif
35
36 #include "wx/string.h"
37
38 #ifndef WXDEBUG_NEW
39 #define WXDEBUG_NEW new(__FILE__,__LINE__)
40 #endif
41
42 #if WXDEBUG
43 void * wxDebugAlloc(size_t size, char * fileName, int lineNum, bool isObject, bool isVect = FALSE);
44 void wxDebugFree(void * buf, bool isVect = FALSE);
45
46 // Global versions of the new and delete operators.
47 // Currently, these merely call malloc and free; only the wxObject
48 // operators do something interesting. But this allows WXDEBUG_NEW to
49 // work for all 'new's in a file.
50 #if USE_GLOBAL_MEMORY_OPERATORS
51
52 #ifdef new
53 #undef new
54 #endif
55
56 void * operator new (size_t size, char * fileName, int lineNum);
57 void operator delete (void * buf);
58
59 #if !( defined (_MSC_VER) && (_MSC_VER <= 1000) )
60 void * operator new[] (size_t size, char * fileName, int lineNum);
61 void operator delete[] (void * buf);
62 #endif
63
64 #define new WXDEBUG_NEW
65
66 #endif
67 #endif
68
69 typedef unsigned int wxMarkerType;
70
71 /*
72 Define the struct which will be placed at the start of all dynamically
73 allocated memory.
74 */
75
76 class WXDLLEXPORT wxMemStruct {
77
78 friend class WXDLLEXPORT wxDebugContext; // access to the m_next pointer for list traversal.
79
80 public:
81 public:
82 int AssertList ();
83
84 size_t RequestSize () { return m_reqSize; }
85 wxMarkerType Marker () { return m_firstMarker; }
86
87 // When an object is deleted we set the id slot to a specific value.
88 inline void SetDeleted ();
89 inline int IsDeleted ();
90
91 int Append ();
92 int Unlink ();
93
94 // Used to determine if the object is really a wxMemStruct.
95 // Not a foolproof test by any means, but better than none I hope!
96 int AssertIt ();
97
98 // Do all validation on a node.
99 int ValidateNode ();
100
101 // Check the integrity of a node and of the list, node by node.
102 int CheckBlock ();
103 int CheckAllPrevious ();
104
105 // Print a single node.
106 void PrintNode ();
107
108 // Called when the memory linking functions get an error.
109 void ErrorMsg (const char *);
110 void ErrorMsg ();
111
112 inline void *GetActualData(void) const { return m_actualData; }
113
114 void Dump(void);
115
116 public:
117 // Check for underwriting. There are 2 of these checks. This one
118 // inside the struct and another right after the struct.
119 wxMarkerType m_firstMarker;
120
121 // File name and line number are from cpp.
122 char* m_fileName;
123 int m_lineNum;
124
125 // The amount of memory requested by the caller.
126 size_t m_reqSize;
127
128 // Used to try to verify that we really are dealing with an object
129 // of the required class. Can be 1 of 2 values these indicating a valid
130 // wxMemStruct object, or a deleted wxMemStruct object.
131 wxMarkerType m_id;
132
133 wxMemStruct * m_prev;
134 wxMemStruct * m_next;
135
136 void * m_actualData;
137 bool m_isObject;
138 };
139
140
141 typedef void (wxMemStruct::*PmSFV) ();
142
143
144 /*
145 Debugging class. This will only have a single instance, but it\'s
146 a reasonable way to keep everything together and to make this
147 available for change if needed by someone else.
148 A lot of this stuff would be better off within the wxMemStruct class, but
149 it\'s stuff which we need to access at times when there is no wxMemStruct
150 object so we use this class instead. Think of it as a collection of
151 globals which have to do with the wxMemStruct class.
152 */
153
154 class WXDLLEXPORT wxDebugContext {
155
156 protected:
157 // Used to set alignment for markers.
158 static size_t CalcAlignment ();
159
160 // Returns the amount of padding needed after something of the given
161 // size. This is so that when we cast pointers backwards and forwards
162 // the pointer value will be valid for a wxMarkerType.
163 static size_t GetPadding (const size_t size) ;
164
165 // Traverse the list.
166 static void TraverseList (PmSFV, wxMemStruct *from = NULL);
167
168 static streambuf *m_streamBuf;
169 static ostream *m_debugStream;
170
171 static int debugLevel;
172 static bool debugOn;
173
174 public:
175 // Set a checkpoint to dump only the memory from
176 // a given point
177 static wxMemStruct *checkPoint;
178
179 wxDebugContext(void);
180 ~wxDebugContext(void);
181
182 static bool HasStream(void) { return (m_debugStream != NULL); };
183 static ostream& GetStream(void) { return *m_debugStream; }
184 static streambuf *GetStreamBuf(void) { return m_streamBuf; }
185 static void SetStream(ostream *stream, streambuf *buf = NULL);
186 static bool SetFile(const wxString& file);
187 static bool SetStandardError(void);
188
189 static int GetLevel(void) { return debugLevel; }
190 static void SetLevel(int level) { debugLevel = level; }
191
192 static bool GetDebugMode(void) { return debugOn; }
193 static void SetDebugMode(bool flag) { debugOn = flag; }
194
195 static void SetCheckpoint(bool all = FALSE);
196 static wxMemStruct *GetCheckpoint(void) { return checkPoint; }
197
198 // Calculated from the request size and any padding needed
199 // before the final marker.
200 static size_t PaddedSize (const size_t reqSize);
201
202 // Calc the total amount of space we need from the system
203 // to satisfy a caller request. This includes all padding.
204 static size_t TotSize (const size_t reqSize);
205
206 // Return valid pointers to offsets within the allocated memory.
207 static char * StructPos (const char * buf);
208 static char * MidMarkerPos (const char * buf);
209 static char * CallerMemPos (const char * buf);
210 static char * EndMarkerPos (const char * buf, const size_t size);
211
212 // Given a pointer to the start of the caller requested area
213 // return a pointer to the start of the entire alloc\'d buffer.
214 static char * StartPos (const char * caller);
215
216 // Access to the list.
217 static wxMemStruct * GetHead () { return m_head; }
218 static wxMemStruct * GetTail () { return m_tail; }
219
220 // Set the list sentinals.
221 static wxMemStruct * SetHead (wxMemStruct * st) { return (m_head = st); }
222 static wxMemStruct * SetTail (wxMemStruct * st) { return (m_tail = st); }
223
224 // If this is set then every new operation checks the validity
225 // of the all previous nodes in the list.
226 static bool GetCheckPrevious () { return m_checkPrevious; }
227 static void SetCheckPrevious (bool value) { m_checkPrevious = value; }
228
229 // Checks all nodes, or all nodes if checkAll is TRUE
230 static int Check(bool checkAll = FALSE);
231
232 // Print out the list of wxMemStruct nodes.
233 static bool PrintList(void);
234
235 // Dump objects
236 static bool Dump(void);
237
238 // Print statistics
239 static bool PrintStatistics(bool detailed = TRUE);
240
241 // Print out the classes in the application.
242 static bool PrintClasses(void);
243
244 // Count the number of non-wxDebugContext-related objects
245 // that are outstanding
246 static int CountObjectsLeft(void);
247
248 private:
249 // Store these here to allow access to the list without
250 // needing to have a wxMemStruct object.
251 static wxMemStruct* m_head;
252 static wxMemStruct* m_tail;
253
254 // Set to FALSE if we're not checking all previous nodes when
255 // we do a new. Set to TRUE when we are.
256 static bool m_checkPrevious;
257 };
258
259 // Output a debug mess., in a system dependent fashion.
260 void WXDLLEXPORT wxTrace(const char *fmt ...);
261 void WXDLLEXPORT wxTraceLevel(int level, const char *fmt ...);
262
263 #define WXTRACE wxTrace
264 #define WXTRACELEVEL wxTraceLevel
265
266 #else // else part for the #if WXDEBUG
267
268 inline void wxTrace(const char *WXUNUSED(fmt)) {}
269 inline void wxTraceLevel(int WXUNUSED(level), const char *WXUNUSED(fmt)) {}
270
271 #define WXTRACE TRUE ? (void)0 : wxTrace
272 #define WXTRACELEVEL TRUE ? (void)0 : wxTraceLevel
273 #define WXDEBUG_NEW new
274
275 #endif // WXDEBUG
276
277 #endif
278 // __MEMORYH__
279