VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstMemAutoPtr.cpp@ 31157

Last change on this file since 31157 was 31157, checked in by vboxsync, 14 years ago

iprt,++: Tag allocation in all builds with a string, defaulting to FILE.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.6 KB
Line 
1/* $Id: tstMemAutoPtr.cpp 31157 2010-07-28 03:15:35Z vboxsync $ */
2/** @file
3 * IPRT - Testcase the RTMemAutoPtr template.
4 */
5
6/*
7 * Copyright (C) 2008-2010 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27/*******************************************************************************
28* Header Files *
29*******************************************************************************/
30#include <iprt/mem.h>
31#include <iprt/stream.h>
32#include <iprt/initterm.h>
33#include <iprt/string.h>
34#include <iprt/rand.h>
35
36
37/*******************************************************************************
38* Structures and Typedefs *
39*******************************************************************************/
40typedef struct TSTMEMAUTOPTRSTRUCT
41{
42 uint32_t a;
43 uint32_t b;
44 uint32_t c;
45} TSTMEMAUTOPTRSTRUCT;
46
47
48/*******************************************************************************
49* Global Variables *
50*******************************************************************************/
51#ifndef TST_MEM_AUTO_PTR_ONLY_DISAS
52static unsigned g_cErrors = 0;
53static unsigned g_cFrees;
54#endif
55
56
57/*
58 * Feel free to inspect with gdb / objdump / whatever / g++ -fverbose-asm in
59 * a release build and compare with tstMemAutoPtrDisas1PureC.
60 */
61extern "C" int tstMemAutoPtrDisas1(void **ppv)
62{
63 RTMemAutoPtr<TSTMEMAUTOPTRSTRUCT> Handle(1);
64 if (!Handle)
65 {
66 Handle->a = RTRandU32();
67 if (Handle->a < UINT32_MAX / 2)
68 {
69 *ppv = Handle.release();
70 return VINF_SUCCESS;
71 }
72 }
73 return VERR_TRY_AGAIN;
74}
75
76/*
77 * For comparing to tstMemAutoPtrDisas1.
78 */
79extern "C" int tstMemAutoPtrDisas1PureC(void **ppv)
80{
81 TSTMEMAUTOPTRSTRUCT *pHandle = (TSTMEMAUTOPTRSTRUCT *)RTMemRealloc(NULL, sizeof(*pHandle));
82 if (pHandle)
83 {
84 pHandle->a = RTRandU32();
85 if (pHandle->a < UINT32_MAX / 2)
86 {
87 *ppv = pHandle;
88 return VINF_SUCCESS;
89 }
90 RTMemFree(pHandle);
91 }
92 return VERR_TRY_AGAIN;
93}
94
95
96#ifndef TST_MEM_AUTO_PTR_ONLY_DISAS
97
98template <class T>
99void tstMemAutoPtrDestructorCounter(T *aMem)
100{
101 if (aMem == NULL)
102 {
103 RTPrintf("tstMemAutoPtr(%d): Destructor called with NILL handle!\n");
104 g_cErrors++;
105 }
106 else if (!VALID_PTR(aMem))
107 {
108 RTPrintf("tstMemAutoPtr(%d): Destructor called with a bad handle %p\n", aMem);
109 g_cErrors++;
110 }
111 RTMemEfFreeNP(aMem);
112 g_cFrees++;
113}
114
115
116void *tstMemAutoPtrAllocatorNoZero(void *pvOld, size_t cbNew, const char *pszTag)
117{
118 void *pvNew = RTMemReallocTag(pvOld, cbNew, pszTag);
119 if (pvNew)
120 memset(pvNew, 0xfe, cbNew);
121 return pvNew;
122}
123
124
125int main()
126{
127 RTR3Init();
128 RTPrintf("tstMemAutoPtr: TESTING...\n");
129
130#define CHECK_EXPR(expr) \
131 do { bool const f = !!(expr); if (!f) { RTPrintf("tstMemAutoPtr(%d): %s!\n", __LINE__, #expr); g_cErrors++; } } while (0)
132
133 /*
134 * Some simple stuff.
135 */
136 {
137 RTMemAutoPtr<char> NilObj;
138 CHECK_EXPR(!NilObj);
139 CHECK_EXPR(NilObj.get() == NULL);
140 CHECK_EXPR(NilObj.release() == NULL);
141 NilObj.reset();
142 }
143
144 {
145 RTMemAutoPtr<char> Alloc(10);
146 CHECK_EXPR(Alloc.get() != NULL);
147 char *pch = Alloc.release();
148 CHECK_EXPR(pch != NULL);
149 CHECK_EXPR(Alloc.get() == NULL);
150
151 RTMemAutoPtr<char> Manage(pch);
152 CHECK_EXPR(Manage.get() == pch);
153 CHECK_EXPR(&Manage[0] == pch);
154 CHECK_EXPR(&Manage[1] == &pch[1]);
155 CHECK_EXPR(&Manage[9] == &pch[9]);
156 }
157
158 /*
159 * Use the electric fence memory API to check alternative template
160 * arguments and also check some subscript / reference limit thing.
161 */
162 {
163 RTMemAutoPtr<char, RTMemEfAutoFree<char>, RTMemEfReallocNP> Electric(10);
164 CHECK_EXPR(Electric.get() != NULL);
165 Electric[0] = '0';
166 CHECK_EXPR(Electric[0] == '0');
167 CHECK_EXPR(*Electric == '0');
168 //CHECK_EXPR(Electric == '0');
169 Electric[9] = '1';
170 CHECK_EXPR(Electric[9] == '1');
171 /* Electric[10] = '2'; - this will crash (of course) */
172 }
173
174 /*
175 * Check that memory is actually free when it should be and isn't when it shouldn't.
176 * Use the electric heap to get some extra checks.
177 */
178 g_cFrees = 0;
179 {
180 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt(128);
181 FreeIt[127] = '0';
182 }
183 CHECK_EXPR(g_cFrees == 1);
184
185 g_cFrees = 0;
186 {
187 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt2(128);
188 FreeIt2[127] = '1';
189 FreeIt2.reset();
190 FreeIt2.alloc(128);
191 FreeIt2[127] = '2';
192 FreeIt2.reset(FreeIt2.get()); /* this one is weird, but it's how things works... */
193 }
194 CHECK_EXPR(g_cFrees == 2);
195
196 g_cFrees = 0;
197 {
198 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> DontFreeIt(256);
199 DontFreeIt[255] = '0';
200 RTMemEfFreeNP(DontFreeIt.release());
201 }
202 CHECK_EXPR(g_cFrees == 0);
203
204 g_cFrees = 0;
205 {
206 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt3(128);
207 FreeIt3[127] = '0';
208 CHECK_EXPR(FreeIt3.realloc(128));
209 FreeIt3[127] = '0';
210 CHECK_EXPR(FreeIt3.realloc(256));
211 FreeIt3[255] = '0';
212 CHECK_EXPR(FreeIt3.realloc(64));
213 FreeIt3[63] = '0';
214 CHECK_EXPR(FreeIt3.realloc(32));
215 FreeIt3[31] = '0';
216 }
217 CHECK_EXPR(g_cFrees == 1);
218
219 g_cFrees = 0;
220 {
221 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfReallocNP> FreeIt4;
222 CHECK_EXPR(FreeIt4.alloc(123));
223 CHECK_EXPR(FreeIt4.realloc(543));
224 FreeIt4 = (char *)NULL;
225 CHECK_EXPR(FreeIt4.get() == NULL);
226 }
227 CHECK_EXPR(g_cFrees == 1);
228
229 /*
230 * Check the ->, [] and * (unary) operators with some useful struct.
231 */
232 {
233 RTMemAutoPtr<TSTMEMAUTOPTRSTRUCT> Struct1(1);
234 Struct1->a = 0x11223344;
235 Struct1->b = 0x55667788;
236 Struct1->c = 0x99aabbcc;
237 CHECK_EXPR(Struct1->a == 0x11223344);
238 CHECK_EXPR(Struct1->b == 0x55667788);
239 CHECK_EXPR(Struct1->c == 0x99aabbcc);
240
241 Struct1[0].a = 0x11223344;
242 Struct1[0].b = 0x55667788;
243 Struct1[0].c = 0x99aabbcc;
244 CHECK_EXPR(Struct1[0].a == 0x11223344);
245 CHECK_EXPR(Struct1[0].b == 0x55667788);
246 CHECK_EXPR(Struct1[0].c == 0x99aabbcc);
247
248 (*Struct1).a = 0x11223344;
249 (*Struct1).b = 0x55667788;
250 (*Struct1).c = 0x99aabbcc;
251 CHECK_EXPR((*Struct1).a == 0x11223344);
252 CHECK_EXPR((*Struct1).b == 0x55667788);
253 CHECK_EXPR((*Struct1).c == 0x99aabbcc);
254
255 /* since at it... */
256 Struct1.get()->a = 0x11223344;
257 Struct1.get()->b = 0x55667788;
258 Struct1.get()->c = 0x99aabbcc;
259 CHECK_EXPR(Struct1.get()->a == 0x11223344);
260 CHECK_EXPR(Struct1.get()->b == 0x55667788);
261 CHECK_EXPR(Struct1.get()->c == 0x99aabbcc);
262 }
263
264 /*
265 * Check the zeroing of memory.
266 */
267 {
268 RTMemAutoPtr<uint64_t, RTMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed1(1, true);
269 CHECK_EXPR(*Zeroed1 == 0);
270 }
271
272 {
273 RTMemAutoPtr<uint64_t, RTMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed2;
274 Zeroed2.alloc(5, true);
275 CHECK_EXPR(Zeroed2[0] == 0);
276 CHECK_EXPR(Zeroed2[1] == 0);
277 CHECK_EXPR(Zeroed2[2] == 0);
278 CHECK_EXPR(Zeroed2[3] == 0);
279 CHECK_EXPR(Zeroed2[4] == 0);
280 }
281
282 /*
283 * Summary.
284 */
285 if (!g_cErrors)
286 RTPrintf("tstMemAutoPtr: SUCCESS\n");
287 else
288 RTPrintf("tstMemAutoPtr: FAILED - %d errors\n", g_cErrors);
289 return !!g_cErrors;
290}
291#endif /* TST_MEM_AUTO_PTR_ONLY_DISAS */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette