1 ////////////////////////////////////////////////////////////////////////////////
3 // Visual Leak Detector - Internal C++ Heap Management
4 // Copyright (c) 2006 Dan Moulding
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 // See COPYING.txt for the full terms of the GNU Lesser General Public License.
22 ////////////////////////////////////////////////////////////////////////////////
25 #define VLDBUILD // Declares that we are building Visual Leak Detector.
26 #include "ntapi.h" // Provides access to NT APIs.
27 #include "vldheap.h" // Provides access to VLD's internal heap data structures.
28 #undef new // Do not map "new" to VLD's new operator in this file
31 vldblockheader_t *vldblocklist = NULL; // List of internally allocated blocks on VLD's private heap.
32 HANDLE vldheap; // VLD's private heap.
33 CRITICAL_SECTION vldheaplock; // Serializes access to VLD's private heap.
35 // Local helper functions.
36 static inline void vlddelete (void *block);
37 static inline void* vldnew (size_t size, const char *file, int line);
39 // scalar delete operator - Delete operator used to free internally used memory
40 // back to VLD's private heap.
42 // - block (IN): Pointer to the scalar memory block to free.
48 void operator delete (void *block)
53 // vector delete operator - Delete operator used to free internally used memory
54 // back to VLD's private heap.
56 // - block (IN): Pointer to the vector memory block to free.
62 void operator delete [] (void *block)
67 // scalar delete operator - Delete operator used to free memory partially
68 // allocated by new in the event that the corresponding new operator throws
71 // Note: This version of the delete operator should never be called directly.
72 // The compiler automatically generates calls to this function as needed.
74 void operator delete (void *block, const char *, int)
79 // vector delete operator - Delete operator used to free memory partially
80 // allocated by new in the event that the corresponding new operator throws
83 // Note: This version of the delete operator should never be called directly.
84 // The compiler automatically generates calls to this function as needed.
86 void operator delete [] (void *block, const char *, int)
91 // scalar new operator - New operator used to allocate a scalar memory block
92 // from VLD's private heap.
94 // - size (IN): Size of the memory block to be allocated.
96 // - file (IN): The name of the file from which this function is being
99 // - line (IN): The line number, in the above file, at which this function is
104 // If the allocation succeeds, a pointer to the allocated memory block is
105 // returned. If the allocation fails, NULL is returned.
107 void* operator new (size_t size, const char *file, int line)
109 return vldnew(size, file, line);
112 // vector new operator - New operator used to allocate a vector memory block
113 // from VLD's private heap.
115 // - size (IN): Size of the memory block to be allocated.
117 // - file (IN): The name of the file from which this function is being
120 // - line (IN): The line number, in the above file, at which this function is
125 // If the allocation succeeds, a pointer to the allocated memory block is
126 // returned. If the allocation fails, NULL is returned.
128 void* operator new [] (size_t size, const char *file, int line)
130 return vldnew(size, file, line);
133 // vlddelete - Local helper function that actually frees memory back to VLD's
136 // - block (IN): Pointer to a memory block being freed.
142 void vlddelete (void *block)
145 vldblockheader_t *header = VLDBLOCKHEADER((LPVOID)block);
147 // Unlink the block from the block list.
148 EnterCriticalSection(&vldheaplock);
150 header->prev->next = header->next;
153 vldblocklist = header->next;
157 header->next->prev = header->prev;
159 LeaveCriticalSection(&vldheaplock);
162 freed = RtlFreeHeap(vldheap, 0x0, header);
163 assert(freed != FALSE);
166 // vldnew - Local helper function that actually allocates memory from VLD's
167 // private heap. Prepends a header, which is used for bookeeping information
168 // that allows VLD to detect and report internal memory leaks, to the returned
169 // block, but the header is transparent to the caller because the returned
170 // pointer points to the useable section of memory requested by the caller, it
171 // does not point to the block header.
173 // - size (IN): Size of the memory block to be allocated.
175 // - file (IN): Name of the file that called the new operator.
177 // - line (IN): Line, in the above file, at which the new operator was called.
181 // If the memory allocation succeeds, a pointer to the allocated memory
182 // block is returned. If the allocation fails, NULL is returned.
184 void* vldnew (size_t size, const char *file, int line)
186 vldblockheader_t *header = (vldblockheader_t*)RtlAllocateHeap(vldheap, 0x0, size + sizeof(vldblockheader_t));
187 static SIZE_T serialnumber = 0;
189 if (header == NULL) {
194 // Fill in the block's header information.
197 header->serialnumber = serialnumber++;
200 // Link the block into the block list.
201 EnterCriticalSection(&vldheaplock);
202 header->next = vldblocklist;
203 if (header->next != NULL) {
204 header->next->prev = header;
207 vldblocklist = header;
208 LeaveCriticalSection(&vldheaplock);
210 // Return a pointer to the beginning of the data section of the block.
211 return (void*)VLDBLOCKDATA(header);