1 ////////////////////////////////////////////////////////////////////////////////
2 // $Id: vldheap.cpp,v 1.13 2006/11/18 03:12:35 dmouldin Exp $
4 // Visual Leak Detector - Internal C++ Heap Management
5 // Copyright (c) 2006 Dan Moulding
7 // This library is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 // Lesser General Public License for more details.
17 // You should have received a copy of the GNU Lesser General Public
18 // License along with this library; if not, write to the Free Software
19 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 // See COPYING.txt for the full terms of the GNU Lesser General Public License.
23 ////////////////////////////////////////////////////////////////////////////////
26 #define VLDBUILD // Declares that we are building Visual Leak Detector.
27 #include "ntapi.h" // Provides access to NT APIs.
28 #include "vldheap.h" // Provides access to VLD's internal heap data structures.
29 #undef new // Do not map "new" to VLD's new operator in this file
32 vldblockheader_t *vldblocklist = NULL; // List of internally allocated blocks on VLD's private heap.
33 HANDLE vldheap; // VLD's private heap.
34 CRITICAL_SECTION vldheaplock; // Serializes access to VLD's private heap.
36 // Local helper functions.
37 static inline void vlddelete (void *block);
38 static inline void* vldnew (unsigned int size, const char *file, int line);
40 // scalar delete operator - Delete operator used to free internally used memory
41 // back to VLD's private heap.
43 // - block (IN): Pointer to the scalar memory block to free.
49 void operator delete (void *block)
54 // vector delete operator - Delete operator used to free internally used memory
55 // back to VLD's private heap.
57 // - block (IN): Pointer to the vector memory block to free.
63 void operator delete [] (void *block)
68 // scalar delete operator - Delete operator used to free memory partially
69 // allocated by new in the event that the corresponding new operator throws
72 // Note: This version of the delete operator should never be called directly.
73 // The compiler automatically generates calls to this function as needed.
75 void operator delete (void *block, const char *, int)
80 // vector delete operator - Delete operator used to free memory partially
81 // allocated by new in the event that the corresponding new operator throws
84 // Note: This version of the delete operator should never be called directly.
85 // The compiler automatically generates calls to this function as needed.
87 void operator delete [] (void *block, const char *, int)
92 // scalar new operator - New operator used to allocate a scalar memory block
93 // from VLD's private heap.
95 // - size (IN): Size of the memory block to be allocated.
97 // - file (IN): The name of the file from which this function is being
100 // - line (IN): The line number, in the above file, at which this function is
105 // If the allocation succeeds, a pointer to the allocated memory block is
106 // returned. If the allocation fails, NULL is returned.
108 void* operator new (unsigned int size, const char *file, int line)
110 return vldnew(size, file, line);
113 // vector new operator - New operator used to allocate a vector memory block
114 // from VLD's private heap.
116 // - size (IN): Size of the memory block to be allocated.
118 // - file (IN): The name of the file from which this function is being
121 // - line (IN): The line number, in the above file, at which this function is
126 // If the allocation succeeds, a pointer to the allocated memory block is
127 // returned. If the allocation fails, NULL is returned.
129 void* operator new [] (unsigned int size, const char *file, int line)
131 return vldnew(size, file, line);
134 // vlddelete - Local helper function that actually frees memory back to VLD's
137 // - block (IN): Pointer to a memory block being freed.
143 void vlddelete (void *block)
146 vldblockheader_t *header = VLDBLOCKHEADER((LPVOID)block);
148 // Unlink the block from the block list.
149 EnterCriticalSection(&vldheaplock);
151 header->prev->next = header->next;
154 vldblocklist = header->next;
158 header->next->prev = header->prev;
160 LeaveCriticalSection(&vldheaplock);
163 freed = RtlFreeHeap(vldheap, 0x0, header);
164 assert(freed != FALSE);
167 // vldnew - Local helper function that actually allocates memory from VLD's
168 // private heap. Prepends a header, which is used for bookeeping information
169 // that allows VLD to detect and report internal memory leaks, to the returned
170 // block, but the header is transparent to the caller because the returned
171 // pointer points to the useable section of memory requested by the caller, it
172 // does not point to the block header.
174 // - size (IN): Size of the memory block to be allocated.
176 // - file (IN): Name of the file that called the new operator.
178 // - line (IN): Line, in the above file, at which the new operator was called.
182 // If the memory allocation succeeds, a pointer to the allocated memory
183 // block is returned. If the allocation fails, NULL is returned.
185 void* vldnew (unsigned int size, const char *file, int line)
187 vldblockheader_t *header = (vldblockheader_t*)RtlAllocateHeap(vldheap, 0x0, size + sizeof(vldblockheader_t));
188 static SIZE_T serialnumber = 0;
190 if (header == NULL) {
195 // Fill in the block's header information.
198 header->serialnumber = serialnumber++;
201 // Link the block into the block list.
202 EnterCriticalSection(&vldheaplock);
203 header->next = vldblocklist;
204 if (header->next != NULL) {
205 header->next->prev = header;
208 vldblocklist = header;
209 LeaveCriticalSection(&vldheaplock);
211 // Return a pointer to the beginning of the data section of the block.
212 return (void*)VLDBLOCKDATA(header);