Home | History | Annotate | Download | only in common
      1 /*
      2 ******************************************************************************
      3 *
      4 *   Copyright (C) 1997-2015, International Business Machines
      5 *   Corporation and others.  All Rights Reserved.
      6 *
      7 ******************************************************************************
      8 *
      9 * File CMEMORY.H
     10 *
     11 *  Contains stdlib.h/string.h memory functions
     12 *
     13 * @author       Bertrand A. Damiba
     14 *
     15 * Modification History:
     16 *
     17 *   Date        Name        Description
     18 *   6/20/98     Bertrand    Created.
     19 *  05/03/99     stephen     Changed from functions to macros.
     20 *
     21 ******************************************************************************
     22 */
     23 
     24 #ifndef CMEMORY_H
     25 #define CMEMORY_H
     26 
     27 #include "unicode/utypes.h"
     28 
     29 #include <stddef.h>
     30 #include <string.h>
     31 #include "unicode/localpointer.h"
     32 
     33 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
     34 #include <stdio.h>
     35 #endif
     36 
     37 #if U_DEBUG
     38 
     39 /*
     40  * The C++ standard requires that the source pointer for memcpy() & memmove()
     41  * is valid, not NULL, and not at the end of an allocated memory block.
     42  * In debug mode, we read one byte from the source point to verify that it's
     43  * a valid, readable pointer.
     44  */
     45 
     46 U_CAPI void uprv_checkValidMemory(const void *p, size_t n);
     47 
     48 #define uprv_memcpy(dst, src, size) ( \
     49     uprv_checkValidMemory(src, 1), \
     50     U_STANDARD_CPP_NAMESPACE memcpy(dst, src, size))
     51 #define uprv_memmove(dst, src, size) ( \
     52     uprv_checkValidMemory(src, 1), \
     53     U_STANDARD_CPP_NAMESPACE memmove(dst, src, size))
     54 
     55 #else
     56 
     57 #define uprv_memcpy(dst, src, size) U_STANDARD_CPP_NAMESPACE memcpy(dst, src, size)
     58 #define uprv_memmove(dst, src, size) U_STANDARD_CPP_NAMESPACE memmove(dst, src, size)
     59 
     60 #endif  /* U_DEBUG */
     61 
     62 /**
     63  * \def UPRV_LENGTHOF
     64  * Convenience macro to determine the length of a fixed array at compile-time.
     65  * @param array A fixed length array
     66  * @return The length of the array, in elements
     67  * @internal
     68  */
     69 #define UPRV_LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
     70 #define uprv_memset(buffer, mark, size) U_STANDARD_CPP_NAMESPACE memset(buffer, mark, size)
     71 #define uprv_memcmp(buffer1, buffer2, size) U_STANDARD_CPP_NAMESPACE memcmp(buffer1, buffer2,size)
     72 
     73 U_CAPI void * U_EXPORT2
     74 uprv_malloc(size_t s) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR(1);
     75 
     76 U_CAPI void * U_EXPORT2
     77 uprv_realloc(void *mem, size_t size) U_ALLOC_SIZE_ATTR(2);
     78 
     79 U_CAPI void U_EXPORT2
     80 uprv_free(void *mem);
     81 
     82 U_CAPI void * U_EXPORT2
     83 uprv_calloc(size_t num, size_t size) U_MALLOC_ATTR U_ALLOC_SIZE_ATTR2(1,2);
     84 
     85 /**
     86  * This should align the memory properly on any machine.
     87  * This is very useful for the safeClone functions.
     88  */
     89 typedef union {
     90     long    t1;
     91     double  t2;
     92     void   *t3;
     93 } UAlignedMemory;
     94 
     95 /**
     96  * Get the least significant bits of a pointer (a memory address).
     97  * For example, with a mask of 3, the macro gets the 2 least significant bits,
     98  * which will be 0 if the pointer is 32-bit (4-byte) aligned.
     99  *
    100  * ptrdiff_t is the most appropriate integer type to cast to.
    101  * size_t should work too, since on most (or all?) platforms it has the same
    102  * width as ptrdiff_t.
    103  */
    104 #define U_POINTER_MASK_LSB(ptr, mask) (((ptrdiff_t)(char *)(ptr)) & (mask))
    105 
    106 /**
    107  * Get the amount of bytes that a pointer is off by from
    108  * the previous UAlignedMemory-aligned pointer.
    109  */
    110 #define U_ALIGNMENT_OFFSET(ptr) U_POINTER_MASK_LSB(ptr, sizeof(UAlignedMemory) - 1)
    111 
    112 /**
    113  * Get the amount of bytes to add to a pointer
    114  * in order to get the next UAlignedMemory-aligned address.
    115  */
    116 #define U_ALIGNMENT_OFFSET_UP(ptr) (sizeof(UAlignedMemory) - U_ALIGNMENT_OFFSET(ptr))
    117 
    118 /**
    119   *  Heap clean up function, called from u_cleanup()
    120   *    Clears any user heap functions from u_setMemoryFunctions()
    121   *    Does NOT deallocate any remaining allocated memory.
    122   */
    123 U_CFUNC UBool
    124 cmemory_cleanup(void);
    125 
    126 /**
    127  * A function called by <TT>uhash_remove</TT>,
    128  * <TT>uhash_close</TT>, or <TT>uhash_put</TT> to delete
    129  * an existing key or value.
    130  * @param obj A key or value stored in a hashtable
    131  * @see uprv_deleteUObject
    132  */
    133 typedef void U_CALLCONV UObjectDeleter(void* obj);
    134 
    135 /**
    136  * Deleter for UObject instances.
    137  * Works for all subclasses of UObject because it has a virtual destructor.
    138  */
    139 U_CAPI void U_EXPORT2
    140 uprv_deleteUObject(void *obj);
    141 
    142 #ifdef __cplusplus
    143 
    144 U_NAMESPACE_BEGIN
    145 
    146 /**
    147  * "Smart pointer" class, deletes memory via uprv_free().
    148  * For most methods see the LocalPointerBase base class.
    149  * Adds operator[] for array item access.
    150  *
    151  * @see LocalPointerBase
    152  */
    153 template<typename T>
    154 class LocalMemory : public LocalPointerBase<T> {
    155 public:
    156     /**
    157      * Constructor takes ownership.
    158      * @param p simple pointer to an array of T items that is adopted
    159      */
    160     explicit LocalMemory(T *p=NULL) : LocalPointerBase<T>(p) {}
    161 #if U_HAVE_RVALUE_REFERENCES
    162     /**
    163      * Move constructor, leaves src with isNull().
    164      * @param src source smart pointer
    165      */
    166     LocalMemory(LocalMemory<T> &&src) U_NOEXCEPT : LocalPointerBase<T>(src.ptr) {
    167         src.ptr=NULL;
    168     }
    169 #endif
    170     /**
    171      * Destructor deletes the memory it owns.
    172      */
    173     ~LocalMemory() {
    174         uprv_free(LocalPointerBase<T>::ptr);
    175     }
    176 #if U_HAVE_RVALUE_REFERENCES
    177     /**
    178      * Move assignment operator, leaves src with isNull().
    179      * The behavior is undefined if *this and src are the same object.
    180      * @param src source smart pointer
    181      * @return *this
    182      */
    183     LocalMemory<T> &operator=(LocalMemory<T> &&src) U_NOEXCEPT {
    184         return moveFrom(src);
    185     }
    186 #endif
    187     /**
    188      * Move assignment, leaves src with isNull().
    189      * The behavior is undefined if *this and src are the same object.
    190      *
    191      * Can be called explicitly, does not need C++11 support.
    192      * @param src source smart pointer
    193      * @return *this
    194      */
    195     LocalMemory<T> &moveFrom(LocalMemory<T> &src) U_NOEXCEPT {
    196         delete[] LocalPointerBase<T>::ptr;
    197         LocalPointerBase<T>::ptr=src.ptr;
    198         src.ptr=NULL;
    199         return *this;
    200     }
    201     /**
    202      * Swap pointers.
    203      * @param other other smart pointer
    204      */
    205     void swap(LocalMemory<T> &other) U_NOEXCEPT {
    206         T *temp=LocalPointerBase<T>::ptr;
    207         LocalPointerBase<T>::ptr=other.ptr;
    208         other.ptr=temp;
    209     }
    210     /**
    211      * Non-member LocalMemory swap function.
    212      * @param p1 will get p2's pointer
    213      * @param p2 will get p1's pointer
    214      */
    215     friend inline void swap(LocalMemory<T> &p1, LocalMemory<T> &p2) U_NOEXCEPT {
    216         p1.swap(p2);
    217     }
    218     /**
    219      * Deletes the array it owns,
    220      * and adopts (takes ownership of) the one passed in.
    221      * @param p simple pointer to an array of T items that is adopted
    222      */
    223     void adoptInstead(T *p) {
    224         uprv_free(LocalPointerBase<T>::ptr);
    225         LocalPointerBase<T>::ptr=p;
    226     }
    227     /**
    228      * Deletes the array it owns, allocates a new one and reset its bytes to 0.
    229      * Returns the new array pointer.
    230      * If the allocation fails, then the current array is unchanged and
    231      * this method returns NULL.
    232      * @param newCapacity must be >0
    233      * @return the allocated array pointer, or NULL if the allocation failed
    234      */
    235     inline T *allocateInsteadAndReset(int32_t newCapacity=1);
    236     /**
    237      * Deletes the array it owns and allocates a new one, copying length T items.
    238      * Returns the new array pointer.
    239      * If the allocation fails, then the current array is unchanged and
    240      * this method returns NULL.
    241      * @param newCapacity must be >0
    242      * @param length number of T items to be copied from the old array to the new one;
    243      *               must be no more than the capacity of the old array,
    244      *               which the caller must track because the LocalMemory does not track it
    245      * @return the allocated array pointer, or NULL if the allocation failed
    246      */
    247     inline T *allocateInsteadAndCopy(int32_t newCapacity=1, int32_t length=0);
    248     /**
    249      * Array item access (writable).
    250      * No index bounds check.
    251      * @param i array index
    252      * @return reference to the array item
    253      */
    254     T &operator[](ptrdiff_t i) const { return LocalPointerBase<T>::ptr[i]; }
    255 };
    256 
    257 template<typename T>
    258 inline T *LocalMemory<T>::allocateInsteadAndReset(int32_t newCapacity) {
    259     if(newCapacity>0) {
    260         T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
    261         if(p!=NULL) {
    262             uprv_memset(p, 0, newCapacity*sizeof(T));
    263             uprv_free(LocalPointerBase<T>::ptr);
    264             LocalPointerBase<T>::ptr=p;
    265         }
    266         return p;
    267     } else {
    268         return NULL;
    269     }
    270 }
    271 
    272 
    273 template<typename T>
    274 inline T *LocalMemory<T>::allocateInsteadAndCopy(int32_t newCapacity, int32_t length) {
    275     if(newCapacity>0) {
    276         T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
    277         if(p!=NULL) {
    278             if(length>0) {
    279                 if(length>newCapacity) {
    280                     length=newCapacity;
    281                 }
    282                 uprv_memcpy(p, LocalPointerBase<T>::ptr, length*sizeof(T));
    283             }
    284             uprv_free(LocalPointerBase<T>::ptr);
    285             LocalPointerBase<T>::ptr=p;
    286         }
    287         return p;
    288     } else {
    289         return NULL;
    290     }
    291 }
    292 
    293 /**
    294  * Simple array/buffer management class using uprv_malloc() and uprv_free().
    295  * Provides an internal array with fixed capacity. Can alias another array
    296  * or allocate one.
    297  *
    298  * The array address is properly aligned for type T. It might not be properly
    299  * aligned for types larger than T (or larger than the largest subtype of T).
    300  *
    301  * Unlike LocalMemory and LocalArray, this class never adopts
    302  * (takes ownership of) another array.
    303  */
    304 template<typename T, int32_t stackCapacity>
    305 class MaybeStackArray {
    306 public:
    307     /**
    308      * Default constructor initializes with internal T[stackCapacity] buffer.
    309      */
    310     MaybeStackArray() : ptr(stackArray), capacity(stackCapacity), needToRelease(FALSE) {}
    311     /**
    312      * Destructor deletes the array (if owned).
    313      */
    314     ~MaybeStackArray() { releaseArray(); }
    315     /**
    316      * Returns the array capacity (number of T items).
    317      * @return array capacity
    318      */
    319     int32_t getCapacity() const { return capacity; }
    320     /**
    321      * Access without ownership change.
    322      * @return the array pointer
    323      */
    324     T *getAlias() const { return ptr; }
    325     /**
    326      * Returns the array limit. Simple convenience method.
    327      * @return getAlias()+getCapacity()
    328      */
    329     T *getArrayLimit() const { return getAlias()+capacity; }
    330     // No "operator T *() const" because that can make
    331     // expressions like mbs[index] ambiguous for some compilers.
    332     /**
    333      * Array item access (const).
    334      * No index bounds check.
    335      * @param i array index
    336      * @return reference to the array item
    337      */
    338     const T &operator[](ptrdiff_t i) const { return ptr[i]; }
    339     /**
    340      * Array item access (writable).
    341      * No index bounds check.
    342      * @param i array index
    343      * @return reference to the array item
    344      */
    345     T &operator[](ptrdiff_t i) { return ptr[i]; }
    346     /**
    347      * Deletes the array (if owned) and aliases another one, no transfer of ownership.
    348      * If the arguments are illegal, then the current array is unchanged.
    349      * @param otherArray must not be NULL
    350      * @param otherCapacity must be >0
    351      */
    352     void aliasInstead(T *otherArray, int32_t otherCapacity) {
    353         if(otherArray!=NULL && otherCapacity>0) {
    354             releaseArray();
    355             ptr=otherArray;
    356             capacity=otherCapacity;
    357             needToRelease=FALSE;
    358         }
    359     }
    360     /**
    361      * Deletes the array (if owned) and allocates a new one, copying length T items.
    362      * Returns the new array pointer.
    363      * If the allocation fails, then the current array is unchanged and
    364      * this method returns NULL.
    365      * @param newCapacity can be less than or greater than the current capacity;
    366      *                    must be >0
    367      * @param length number of T items to be copied from the old array to the new one
    368      * @return the allocated array pointer, or NULL if the allocation failed
    369      */
    370     inline T *resize(int32_t newCapacity, int32_t length=0);
    371     /**
    372      * Gives up ownership of the array if owned, or else clones it,
    373      * copying length T items; resets itself to the internal stack array.
    374      * Returns NULL if the allocation failed.
    375      * @param length number of T items to copy when cloning,
    376      *        and capacity of the clone when cloning
    377      * @param resultCapacity will be set to the returned array's capacity (output-only)
    378      * @return the array pointer;
    379      *         caller becomes responsible for deleting the array
    380      */
    381     inline T *orphanOrClone(int32_t length, int32_t &resultCapacity);
    382 private:
    383     T *ptr;
    384     int32_t capacity;
    385     UBool needToRelease;
    386     T stackArray[stackCapacity];
    387     void releaseArray() {
    388         if(needToRelease) {
    389             uprv_free(ptr);
    390         }
    391     }
    392     /* No comparison operators with other MaybeStackArray's. */
    393     bool operator==(const MaybeStackArray & /*other*/) {return FALSE;}
    394     bool operator!=(const MaybeStackArray & /*other*/) {return TRUE;}
    395     /* No ownership transfer: No copy constructor, no assignment operator. */
    396     MaybeStackArray(const MaybeStackArray & /*other*/) {}
    397     void operator=(const MaybeStackArray & /*other*/) {}
    398 
    399     // No heap allocation. Use only on the stack.
    400     //   (Declaring these functions private triggers a cascade of problems:
    401     //      MSVC insists on exporting an instantiation of MaybeStackArray, which
    402     //      requires that all functions be defined.
    403     //      An empty implementation of new() is rejected, it must return a value.
    404     //      Returning NULL is rejected by gcc for operator new.
    405     //      The expedient thing is just not to override operator new.
    406     //      While relatively pointless, heap allocated instances will function.
    407     // static void * U_EXPORT2 operator new(size_t size);
    408     // static void * U_EXPORT2 operator new[](size_t size);
    409 #if U_HAVE_PLACEMENT_NEW
    410     // static void * U_EXPORT2 operator new(size_t, void *ptr);
    411 #endif
    412 };
    413 
    414 template<typename T, int32_t stackCapacity>
    415 inline T *MaybeStackArray<T, stackCapacity>::resize(int32_t newCapacity, int32_t length) {
    416     if(newCapacity>0) {
    417 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
    418       ::fprintf(::stderr,"MaybeStacArray (resize) alloc %d * %lu\n", newCapacity,sizeof(T));
    419 #endif
    420         T *p=(T *)uprv_malloc(newCapacity*sizeof(T));
    421         if(p!=NULL) {
    422             if(length>0) {
    423                 if(length>capacity) {
    424                     length=capacity;
    425                 }
    426                 if(length>newCapacity) {
    427                     length=newCapacity;
    428                 }
    429                 uprv_memcpy(p, ptr, length*sizeof(T));
    430             }
    431             releaseArray();
    432             ptr=p;
    433             capacity=newCapacity;
    434             needToRelease=TRUE;
    435         }
    436         return p;
    437     } else {
    438         return NULL;
    439     }
    440 }
    441 
    442 template<typename T, int32_t stackCapacity>
    443 inline T *MaybeStackArray<T, stackCapacity>::orphanOrClone(int32_t length, int32_t &resultCapacity) {
    444     T *p;
    445     if(needToRelease) {
    446         p=ptr;
    447     } else if(length<=0) {
    448         return NULL;
    449     } else {
    450         if(length>capacity) {
    451             length=capacity;
    452         }
    453         p=(T *)uprv_malloc(length*sizeof(T));
    454 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
    455       ::fprintf(::stderr,"MaybeStacArray (orphan) alloc %d * %lu\n", length,sizeof(T));
    456 #endif
    457         if(p==NULL) {
    458             return NULL;
    459         }
    460         uprv_memcpy(p, ptr, length*sizeof(T));
    461     }
    462     resultCapacity=length;
    463     ptr=stackArray;
    464     capacity=stackCapacity;
    465     needToRelease=FALSE;
    466     return p;
    467 }
    468 
    469 /**
    470  * Variant of MaybeStackArray that allocates a header struct and an array
    471  * in one contiguous memory block, using uprv_malloc() and uprv_free().
    472  * Provides internal memory with fixed array capacity. Can alias another memory
    473  * block or allocate one.
    474  * The stackCapacity is the number of T items in the internal memory,
    475  * not counting the H header.
    476  * Unlike LocalMemory and LocalArray, this class never adopts
    477  * (takes ownership of) another memory block.
    478  */
    479 template<typename H, typename T, int32_t stackCapacity>
    480 class MaybeStackHeaderAndArray {
    481 public:
    482     /**
    483      * Default constructor initializes with internal H+T[stackCapacity] buffer.
    484      */
    485     MaybeStackHeaderAndArray() : ptr(&stackHeader), capacity(stackCapacity), needToRelease(FALSE) {}
    486     /**
    487      * Destructor deletes the memory (if owned).
    488      */
    489     ~MaybeStackHeaderAndArray() { releaseMemory(); }
    490     /**
    491      * Returns the array capacity (number of T items).
    492      * @return array capacity
    493      */
    494     int32_t getCapacity() const { return capacity; }
    495     /**
    496      * Access without ownership change.
    497      * @return the header pointer
    498      */
    499     H *getAlias() const { return ptr; }
    500     /**
    501      * Returns the array start.
    502      * @return array start, same address as getAlias()+1
    503      */
    504     T *getArrayStart() const { return reinterpret_cast<T *>(getAlias()+1); }
    505     /**
    506      * Returns the array limit.
    507      * @return array limit
    508      */
    509     T *getArrayLimit() const { return getArrayStart()+capacity; }
    510     /**
    511      * Access without ownership change. Same as getAlias().
    512      * A class instance can be used directly in expressions that take a T *.
    513      * @return the header pointer
    514      */
    515     operator H *() const { return ptr; }
    516     /**
    517      * Array item access (writable).
    518      * No index bounds check.
    519      * @param i array index
    520      * @return reference to the array item
    521      */
    522     T &operator[](ptrdiff_t i) { return getArrayStart()[i]; }
    523     /**
    524      * Deletes the memory block (if owned) and aliases another one, no transfer of ownership.
    525      * If the arguments are illegal, then the current memory is unchanged.
    526      * @param otherArray must not be NULL
    527      * @param otherCapacity must be >0
    528      */
    529     void aliasInstead(H *otherMemory, int32_t otherCapacity) {
    530         if(otherMemory!=NULL && otherCapacity>0) {
    531             releaseMemory();
    532             ptr=otherMemory;
    533             capacity=otherCapacity;
    534             needToRelease=FALSE;
    535         }
    536     }
    537     /**
    538      * Deletes the memory block (if owned) and allocates a new one,
    539      * copying the header and length T array items.
    540      * Returns the new header pointer.
    541      * If the allocation fails, then the current memory is unchanged and
    542      * this method returns NULL.
    543      * @param newCapacity can be less than or greater than the current capacity;
    544      *                    must be >0
    545      * @param length number of T items to be copied from the old array to the new one
    546      * @return the allocated pointer, or NULL if the allocation failed
    547      */
    548     inline H *resize(int32_t newCapacity, int32_t length=0);
    549     /**
    550      * Gives up ownership of the memory if owned, or else clones it,
    551      * copying the header and length T array items; resets itself to the internal memory.
    552      * Returns NULL if the allocation failed.
    553      * @param length number of T items to copy when cloning,
    554      *        and array capacity of the clone when cloning
    555      * @param resultCapacity will be set to the returned array's capacity (output-only)
    556      * @return the header pointer;
    557      *         caller becomes responsible for deleting the array
    558      */
    559     inline H *orphanOrClone(int32_t length, int32_t &resultCapacity);
    560 private:
    561     H *ptr;
    562     int32_t capacity;
    563     UBool needToRelease;
    564     // stackHeader must precede stackArray immediately.
    565     H stackHeader;
    566     T stackArray[stackCapacity];
    567     void releaseMemory() {
    568         if(needToRelease) {
    569             uprv_free(ptr);
    570         }
    571     }
    572     /* No comparison operators with other MaybeStackHeaderAndArray's. */
    573     bool operator==(const MaybeStackHeaderAndArray & /*other*/) {return FALSE;}
    574     bool operator!=(const MaybeStackHeaderAndArray & /*other*/) {return TRUE;}
    575     /* No ownership transfer: No copy constructor, no assignment operator. */
    576     MaybeStackHeaderAndArray(const MaybeStackHeaderAndArray & /*other*/) {}
    577     void operator=(const MaybeStackHeaderAndArray & /*other*/) {}
    578 
    579     // No heap allocation. Use only on the stack.
    580     //   (Declaring these functions private triggers a cascade of problems;
    581     //    see the MaybeStackArray class for details.)
    582     // static void * U_EXPORT2 operator new(size_t size);
    583     // static void * U_EXPORT2 operator new[](size_t size);
    584 #if U_HAVE_PLACEMENT_NEW
    585     // static void * U_EXPORT2 operator new(size_t, void *ptr);
    586 #endif
    587 };
    588 
    589 template<typename H, typename T, int32_t stackCapacity>
    590 inline H *MaybeStackHeaderAndArray<H, T, stackCapacity>::resize(int32_t newCapacity,
    591                                                                 int32_t length) {
    592     if(newCapacity>=0) {
    593 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
    594       ::fprintf(::stderr,"MaybeStackHeaderAndArray alloc %d + %d * %ul\n", sizeof(H),newCapacity,sizeof(T));
    595 #endif
    596         H *p=(H *)uprv_malloc(sizeof(H)+newCapacity*sizeof(T));
    597         if(p!=NULL) {
    598             if(length<0) {
    599                 length=0;
    600             } else if(length>0) {
    601                 if(length>capacity) {
    602                     length=capacity;
    603                 }
    604                 if(length>newCapacity) {
    605                     length=newCapacity;
    606                 }
    607             }
    608             uprv_memcpy(p, ptr, sizeof(H)+length*sizeof(T));
    609             releaseMemory();
    610             ptr=p;
    611             capacity=newCapacity;
    612             needToRelease=TRUE;
    613         }
    614         return p;
    615     } else {
    616         return NULL;
    617     }
    618 }
    619 
    620 template<typename H, typename T, int32_t stackCapacity>
    621 inline H *MaybeStackHeaderAndArray<H, T, stackCapacity>::orphanOrClone(int32_t length,
    622                                                                        int32_t &resultCapacity) {
    623     H *p;
    624     if(needToRelease) {
    625         p=ptr;
    626     } else {
    627         if(length<0) {
    628             length=0;
    629         } else if(length>capacity) {
    630             length=capacity;
    631         }
    632 #if U_DEBUG && defined(UPRV_MALLOC_COUNT)
    633       ::fprintf(::stderr,"MaybeStackHeaderAndArray (orphan) alloc %ul + %d * %lu\n", sizeof(H),length,sizeof(T));
    634 #endif
    635         p=(H *)uprv_malloc(sizeof(H)+length*sizeof(T));
    636         if(p==NULL) {
    637             return NULL;
    638         }
    639         uprv_memcpy(p, ptr, sizeof(H)+length*sizeof(T));
    640     }
    641     resultCapacity=length;
    642     ptr=&stackHeader;
    643     capacity=stackCapacity;
    644     needToRelease=FALSE;
    645     return p;
    646 }
    647 
    648 U_NAMESPACE_END
    649 
    650 #endif  /* __cplusplus */
    651 #endif  /* CMEMORY_H */
    652