Path: blob/master/thirdparty/icu4c/common/cmemory.cpp
9903 views
// © 2016 and later: Unicode, Inc. and others.1// License & terms of use: http://www.unicode.org/copyright.html2/*3******************************************************************************4*5* Copyright (C) 2002-2015, International Business Machines6* Corporation and others. All Rights Reserved.7*8******************************************************************************9*10* File cmemory.c ICU Heap allocation.11* All ICU heap allocation, both for C and C++ new of ICU12* class types, comes through these functions.13*14* If you have a need to replace ICU allocation, this is the15* place to do it.16*17* Note that uprv_malloc(0) returns a non-nullptr pointer,18* and that a subsequent free of that pointer value is a NOP.19*20******************************************************************************21*/22#include "unicode/uclean.h"23#include "cmemory.h"24#include "putilimp.h"25#include "uassert.h"26#include <stdlib.h>2728/* uprv_malloc(0) returns a pointer to this read-only data. */29static const int32_t zeroMem[] = {0, 0, 0, 0, 0, 0};3031/* Function Pointers for user-supplied heap functions */32static const void *pContext;33static UMemAllocFn *pAlloc;34static UMemReallocFn *pRealloc;35static UMemFreeFn *pFree;3637#if U_DEBUG && defined(UPRV_MALLOC_COUNT)38#include <stdio.h>39static int n=0;40static long b=0;41#endif4243U_CAPI void * U_EXPORT244uprv_malloc(size_t s) {45#if U_DEBUG && defined(UPRV_MALLOC_COUNT)46#if 147putchar('>');48fflush(stdout);49#else50fprintf(stderr,"MALLOC\t#%d\t%ul bytes\t%ul total\n", ++n,s,(b+=s)); fflush(stderr);51#endif52#endif53if (s > 0) {54if (pAlloc) {55return (*pAlloc)(pContext, s);56} else {57return uprv_default_malloc(s);58}59} else {60return (void *)zeroMem;61}62}6364U_CAPI void * U_EXPORT265uprv_realloc(void * buffer, size_t size) {66#if U_DEBUG && defined(UPRV_MALLOC_COUNT)67putchar('~');68fflush(stdout);69#endif70if (buffer == zeroMem) {71return uprv_malloc(size);72} else if (size == 0) {73if (pFree) {74(*pFree)(pContext, buffer);75} else {76uprv_default_free(buffer);77}78return (void *)zeroMem;79} else {80if (pRealloc) {81return (*pRealloc)(pContext, buffer, size);82} else {83return uprv_default_realloc(buffer, size);84}85}86}8788U_CAPI void U_EXPORT289uprv_free(void *buffer) {90#if U_DEBUG && defined(UPRV_MALLOC_COUNT)91putchar('<');92fflush(stdout);93#endif94if (buffer != zeroMem) {95if (pFree) {96(*pFree)(pContext, buffer);97} else {98uprv_default_free(buffer);99}100}101}102103U_CAPI void * U_EXPORT2104uprv_calloc(size_t num, size_t size) {105void *mem = nullptr;106size *= num;107mem = uprv_malloc(size);108if (mem) {109uprv_memset(mem, 0, size);110}111return mem;112}113114U_CAPI void U_EXPORT2115u_setMemoryFunctions(const void *context, UMemAllocFn *a, UMemReallocFn *r, UMemFreeFn *f, UErrorCode *status)116{117if (U_FAILURE(*status)) {118return;119}120if (a==nullptr || r==nullptr || f==nullptr) {121*status = U_ILLEGAL_ARGUMENT_ERROR;122return;123}124pContext = context;125pAlloc = a;126pRealloc = r;127pFree = f;128}129130131U_CFUNC UBool cmemory_cleanup() {132pContext = nullptr;133pAlloc = nullptr;134pRealloc = nullptr;135pFree = nullptr;136return true;137}138139140