VirtualBox

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

最後變更 在這個檔案從11017是 11017,由 vboxsync 提交於 17 年 前

iprt: Some RTMemAutoPtr optimizations.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 8.5 KB
 
1/* $Id: tstMemAutoPtr.cpp 11017 2008-07-30 22:27:27Z vboxsync $ */
2/** @file
3 * IPRT - Testcase the RTMemAutoPtr template.
4 */
5
6/*
7 * Copyright (C) 2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include <iprt/mem.h>
35#include <iprt/stream.h>
36#include <iprt/initterm.h>
37#include <iprt/string.h>
38#include <iprt/rand.h>
39
40
41/*******************************************************************************
42* Structures and Typedefs *
43*******************************************************************************/
44typedef struct TSTMEMAUTOPTRSTRUCT
45{
46 uint32_t a;
47 uint32_t b;
48 uint32_t c;
49} TSTMEMAUTOPTRSTRUCT;
50
51
52/*******************************************************************************
53* Global Variables *
54*******************************************************************************/
55static unsigned g_cErrors = 0;
56static unsigned g_cFrees;
57
58
59
60template <class T>
61void tstMemAutoPtrDestructorCounter(T *aMem)
62{
63 if (aMem == NULL)
64 {
65 RTPrintf("tstMemAutoPtr(%d): Destructor called with NILL handle!\n");
66 g_cErrors++;
67 }
68 else if (!VALID_PTR(aMem))
69 {
70 RTPrintf("tstMemAutoPtr(%d): Destructor called with a bad handle %p\n", aMem);
71 g_cErrors++;
72 }
73 RTMemEfFree(aMem);
74 g_cFrees++;
75}
76
77
78void *tstMemAutoPtrAllocatorNoZero(void *pvOld, size_t cbNew)
79{
80 void *pvNew = RTMemRealloc(pvOld, cbNew);
81 if (pvNew)
82 memset(pvNew, 0xfe, cbNew);
83 return pvNew;
84}
85
86
87/*
88 * Feel free to inspect with gdb / objdump / whatever / g++ -fverbose-asm in
89 * a release build and compare with tstMemAutoPtrDisas1PureC.
90 */
91extern "C" int tstMemAutoPtrDisas1(void **ppv)
92{
93 RTMemAutoPtr<TSTMEMAUTOPTRSTRUCT> Handle(1);
94 Handle->a = RTRandU32();
95 if (Handle->a < UINT32_MAX / 2)
96 {
97 *ppv = Handle.release();
98 return VINF_SUCCESS;
99 }
100 return VERR_TRY_AGAIN;
101}
102
103/*
104 * For comparing to tstMemAutoPtrDisas1.
105 */
106extern "C" int tstMemAutoPtrDisas1PureC(void **ppv)
107{
108 TSTMEMAUTOPTRSTRUCT *pHandle = (TSTMEMAUTOPTRSTRUCT *)RTMemRealloc(NULL, sizeof(*pHandle));
109 pHandle->a = RTRandU32();
110 if (pHandle->a < UINT32_MAX / 2)
111 {
112 *ppv = pHandle;
113 return VINF_SUCCESS;
114 }
115 RTMemFree(pHandle);
116 return VERR_TRY_AGAIN;
117}
118
119
120int main()
121{
122 RTR3Init(false);
123 RTPrintf("tstMemAutoPtr: TESTING...\n");
124
125#define CHECK_EXPR(expr) \
126 do { bool const f = !!(expr); if (!f) { RTPrintf("tstMemAutoPtr(%d): %s!\n", __LINE__, #expr); g_cErrors++; } } while (0)
127
128 /*
129 * Some simple stuff.
130 */
131 {
132 RTMemAutoPtr<char> NilObj;
133 CHECK_EXPR(!NilObj);
134 CHECK_EXPR(NilObj.get() == NULL);
135 CHECK_EXPR(NilObj.release() == NULL);
136 NilObj.reset();
137 }
138
139 {
140 RTMemAutoPtr<char> Alloc(10);
141 CHECK_EXPR(Alloc.get() != NULL);
142 char *pch = Alloc.release();
143 CHECK_EXPR(pch != NULL);
144 CHECK_EXPR(Alloc.get() == NULL);
145
146 RTMemAutoPtr<char> Manage(pch);
147 CHECK_EXPR(Manage.get() == pch);
148 CHECK_EXPR(&Manage[0] == pch);
149 CHECK_EXPR(&Manage[1] == &pch[1]);
150 CHECK_EXPR(&Manage[9] == &pch[9]);
151 }
152
153 /*
154 * Use the electric fence memory API to check alternative template
155 * arguments and also check some subscript / reference limit thing.
156 */
157 {
158 RTMemAutoPtr<char, RTMemEfAutoFree<char>, RTMemEfRealloc> Electric(10);
159 CHECK_EXPR(Electric.get() != NULL);
160 Electric[0] = '0';
161 CHECK_EXPR(Electric[0] == '0');
162 CHECK_EXPR(*Electric == '0');
163 //CHECK_EXPR(Electric == '0');
164 Electric[9] = '1';
165 CHECK_EXPR(Electric[9] == '1');
166 /* Electric[10] = '2'; - this will crash (of course) */
167 }
168
169 /*
170 * Check that memory is actually free when it should be and isn't when it shouldn't.
171 * Use the electric heap to get some extra checks.
172 */
173 g_cFrees = 0;
174 {
175 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfRealloc> FreeIt(128);
176 FreeIt[127] = '0';
177 }
178 CHECK_EXPR(g_cFrees == 1);
179
180 g_cFrees = 0;
181 {
182 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfRealloc> FreeIt2(128);
183 FreeIt2[127] = '1';
184 FreeIt2.reset();
185 FreeIt2.alloc(128);
186 FreeIt2[127] = '2';
187 FreeIt2.reset(FreeIt2.get()); /* this one is weird, but it's how things works... */
188 }
189 CHECK_EXPR(g_cFrees == 2);
190
191 g_cFrees = 0;
192 {
193 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfRealloc> DontFreeIt(256);
194 DontFreeIt[255] = '0';
195 RTMemEfFree(DontFreeIt.release());
196 }
197 CHECK_EXPR(g_cFrees == 0);
198
199 g_cFrees = 0;
200 {
201 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfRealloc> FreeIt3(128);
202 FreeIt3[127] = '0';
203 CHECK_EXPR(FreeIt3.realloc(128));
204 FreeIt3[127] = '0';
205 CHECK_EXPR(FreeIt3.realloc(256));
206 FreeIt3[255] = '0';
207 CHECK_EXPR(FreeIt3.realloc(64));
208 FreeIt3[63] = '0';
209 CHECK_EXPR(FreeIt3.realloc(32));
210 FreeIt3[31] = '0';
211 }
212 CHECK_EXPR(g_cFrees == 1);
213
214 g_cFrees = 0;
215 {
216 RTMemAutoPtr<char, tstMemAutoPtrDestructorCounter, RTMemEfRealloc> FreeIt4;
217 CHECK_EXPR(FreeIt4.alloc(123));
218 CHECK_EXPR(FreeIt4.realloc(543));
219 FreeIt4 = (char *)NULL;
220 CHECK_EXPR(FreeIt4.get() == NULL);
221 }
222 CHECK_EXPR(g_cFrees == 1);
223
224 /*
225 * Check the ->, [] and * (unary) operators with some useful struct.
226 */
227 {
228 RTMemAutoPtr<TSTMEMAUTOPTRSTRUCT> Struct1(1);
229 Struct1->a = 0x11223344;
230 Struct1->b = 0x55667788;
231 Struct1->c = 0x99aabbcc;
232 CHECK_EXPR(Struct1->a == 0x11223344);
233 CHECK_EXPR(Struct1->b == 0x55667788);
234 CHECK_EXPR(Struct1->c == 0x99aabbcc);
235
236 Struct1[0].a = 0x11223344;
237 Struct1[0].b = 0x55667788;
238 Struct1[0].c = 0x99aabbcc;
239 CHECK_EXPR(Struct1[0].a == 0x11223344);
240 CHECK_EXPR(Struct1[0].b == 0x55667788);
241 CHECK_EXPR(Struct1[0].c == 0x99aabbcc);
242
243 (*Struct1).a = 0x11223344;
244 (*Struct1).b = 0x55667788;
245 (*Struct1).c = 0x99aabbcc;
246 CHECK_EXPR((*Struct1).a == 0x11223344);
247 CHECK_EXPR((*Struct1).b == 0x55667788);
248 CHECK_EXPR((*Struct1).c == 0x99aabbcc);
249
250 /* since at it... */
251 Struct1.get()->a = 0x11223344;
252 Struct1.get()->b = 0x55667788;
253 Struct1.get()->c = 0x99aabbcc;
254 CHECK_EXPR(Struct1.get()->a == 0x11223344);
255 CHECK_EXPR(Struct1.get()->b == 0x55667788);
256 CHECK_EXPR(Struct1.get()->c == 0x99aabbcc);
257 }
258
259 /*
260 * Check the zeroing of memory.
261 */
262 {
263 RTMemAutoPtr<uint64_t, RTMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed1(1, true);
264 CHECK_EXPR(*Zeroed1 == 0);
265 }
266
267 {
268 RTMemAutoPtr<uint64_t, RTMemAutoDestructor<uint64_t>, tstMemAutoPtrAllocatorNoZero> Zeroed2;
269 Zeroed2.alloc(5, true);
270 CHECK_EXPR(Zeroed2[0] == 0);
271 CHECK_EXPR(Zeroed2[1] == 0);
272 CHECK_EXPR(Zeroed2[2] == 0);
273 CHECK_EXPR(Zeroed2[3] == 0);
274 CHECK_EXPR(Zeroed2[4] == 0);
275 }
276
277 /*
278 * Summary.
279 */
280 if (!g_cErrors)
281 RTPrintf("tstMemAutoPtr: SUCCESS\n");
282 else
283 RTPrintf("tstMemAutoPtr: FAILED - %d errors\n", g_cErrors);
284 return !!g_cErrors;
285}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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