]>
git.saurik.com Git - apple/icu.git/blob - icuSources/common/cmemory.c
2 ******************************************************************************
4 * Copyright (C) 2002-2015, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 ******************************************************************************
9 * File cmemory.c ICU Heap allocation.
10 * All ICU heap allocation, both for C and C++ new of ICU
11 * class types, comes through these functions.
13 * If you have a need to replace ICU allocation, this is the
16 * Note that uprv_malloc(0) returns a non-NULL pointer, and
17 * that a subsequent free of that pointer value is a NOP.
19 ******************************************************************************
21 #include "unicode/uclean.h"
27 /* uprv_malloc(0) returns a pointer to this read-only data. */
28 static const int32_t zeroMem
[] = {0, 0, 0, 0, 0, 0};
30 /* Function Pointers for user-supplied heap functions */
31 static const void *pContext
;
32 static UMemAllocFn
*pAlloc
;
33 static UMemReallocFn
*pRealloc
;
34 static UMemFreeFn
*pFree
;
36 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
44 static char gValidMemorySink
= 0;
46 U_CAPI
void uprv_checkValidMemory(const void *p
, size_t n
) {
48 * Access the memory to ensure that it's all valid.
49 * Load and save a computed value to try to ensure that the compiler
50 * does not throw away the whole loop.
51 * A thread analyzer might complain about un-mutexed access to gValidMemorySink
52 * which is true but harmless because no one ever uses the value in gValidMemorySink.
54 const char *s
= (const char *)p
;
55 char c
= gValidMemorySink
;
58 for(i
= 0; i
< n
; ++i
) {
66 U_CAPI
void * U_EXPORT2
67 uprv_malloc(size_t s
) {
68 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
73 fprintf(stderr
,"MALLOC\t#%d\t%ul bytes\t%ul total\n", ++n
,s
,(b
+=s
)); fflush(stderr
);
78 return (*pAlloc
)(pContext
, s
);
80 return uprv_default_malloc(s
);
83 return (void *)zeroMem
;
87 U_CAPI
void * U_EXPORT2
88 uprv_realloc(void * buffer
, size_t size
) {
89 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
93 if (buffer
== zeroMem
) {
94 return uprv_malloc(size
);
95 } else if (size
== 0) {
97 (*pFree
)(pContext
, buffer
);
99 uprv_default_free(buffer
);
101 return (void *)zeroMem
;
104 return (*pRealloc
)(pContext
, buffer
, size
);
106 return uprv_default_realloc(buffer
, size
);
111 U_CAPI
void U_EXPORT2
112 uprv_free(void *buffer
) {
113 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
117 if (buffer
!= zeroMem
) {
119 (*pFree
)(pContext
, buffer
);
121 uprv_default_free(buffer
);
126 U_CAPI
void * U_EXPORT2
127 uprv_calloc(size_t num
, size_t size
) {
130 mem
= uprv_malloc(size
);
132 uprv_memset(mem
, 0, size
);
137 U_CAPI
void U_EXPORT2
138 u_setMemoryFunctions(const void *context
, UMemAllocFn
*a
, UMemReallocFn
*r
, UMemFreeFn
*f
, UErrorCode
*status
)
140 if (U_FAILURE(*status
)) {
143 if (a
==NULL
|| r
==NULL
|| f
==NULL
) {
144 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
154 U_CFUNC UBool
cmemory_cleanup(void) {