void * __cdecl _calloc_base ( size_t num, size_t size ) { void *retp; REG1 size_t *startptr; REG2 size_t *lastptr; /* try to malloc the requested space */ retp = _malloc_base(size *= num); /* if malloc() succeeded, initialize the allocated space to zeros. * note the assumptions that the size of the allocation block is an * integral number of sizeof(size_t) bytes and that (size_t)0 is * sizeof(size_t) bytes of 0. */ if ( retp != NULL ) { startptr = (size_t *)retp; lastptr = startptr + ((size + sizeof(size_t) - 1) / sizeof(size_t)); while ( startptr < lastptr ) *(startptr++) = 0; } return retp; }
// This function implements the logic of realloc(). It is called directly by // the realloc() and _recalloc() functions in the Release CRT and is called by // the debug heap in the Debug CRT. extern "C" _CRTRESTRICT void* __cdecl _realloc_base( void* const block, size_t const size ) { // If the block is a nullptr, just call malloc: if (block == nullptr) return _malloc_base(size); // If the new size is 0, just call free and return nullptr: if (size == 0) { _free_base(block); return nullptr; } // Ensure that the requested size is not too large: _VALIDATE_RETURN_NOEXC(_HEAP_MAXREQ >= size, ENOMEM, nullptr); for (;;) { void* const new_block = HeapReAlloc(__acrt_heap, 0, block, size); if (new_block) return new_block; // Otherwise, see if we need to call the new handler, and if so call it. // If the new handler fails, just return nullptr: if (_query_new_mode() == 0 || !_callnewh(size)) { errno = ENOMEM; return nullptr; } // The new handler was successful; try to allocate again... } }
__RELIABILITY_CONTRACT const char * type_info::_Name_base(const type_info *_This,__type_info_node* __ptype_info_node) { void *pTmpUndName; size_t len; if (_This->_m_data == NULL) { if ((pTmpUndName = __unDNameHelper(NULL, (_This->_m_d_name)+1, 0, 0)) == NULL) return NULL; /* * Pad all the trailing spaces with null. Note that len-- > 0 is used * at left side which depends on operator associativity. Also note * that len will be used later so don't trash. */ for (len=strlen((char *)pTmpUndName); len-- > 0 && ((char *)pTmpUndName)[len] == ' ';) { ((char *)pTmpUndName)[len] = '\0'; } bool _MustReleaseLock = false; __PREPARE_CONSTRAINED_REGION __TRY __BEGIN_CONSTRAINED_REGION System::Threading::Thread::BeginThreadAffinity(); _mlock(_TYPEINFO_LOCK); _MustReleaseLock = true; __END_CONSTRAINED_REGION /* * We need to check if this->_m_data is still NULL, this will * prevent the memory leak. */ if (_This->_m_data == NULL) { /* * allocate a node which will store the pointer to the memory * allocated for this->_m_data. We need to store all this in * linklist so that we can free them as process exit. Note * that __clean_type_info_names is freeing this memory. */ __type_info_node *pNode = (__type_info_node *)_malloc_base(sizeof(__type_info_node)); if (pNode != NULL) { /* * We should be doing only if we are sucessful in allocating * node pointer. Note that we need to add 2 to len, this * is because len = strlen(pTmpUndName)-1. */ if ((((type_info *)_This)->_m_data = _malloc_base(len+2)) != NULL) { _ERRCHECK(strcpy_s ((char *)((type_info *)_This)->_m_data, len+2, (char *)pTmpUndName)); pNode->memPtr = _This->_m_data; /* * Add this to global linklist. Note that we always * add this as second element in linklist. */ pNode->next = __ptype_info_node->next; __ptype_info_node->next = pNode; } else { /* * Free node pointer as there is no allocation for * this->_m_data, this means that we don't really * need this in the link list. */ _free_base(pNode); } } } /* * Free the temporary undecorated name. */ _free_base (pTmpUndName); __FINALLY if (_MustReleaseLock) { _munlock(_TYPEINFO_LOCK); System::Threading::Thread::EndThreadAffinity(); } __END_TRY_FINALLY } return (char *) _This->_m_data; }
void __cdecl _heap_init ( void ) { #define _INITREGIONSZ 0x1000 /*LATER -- do we need to do anything to init heap? Yes, in case user not malloc first*/ int oldregionsz = _heap_regionsize; /* save current region size */ struct _heap_region_ *pHeapRegions; void *p; void *p2; if (hHeapRegions == NULL) { hHeapRegions = NewHandle(sizeof(struct _heap_region_)*_HEAP_REGIONMAX); if (hHeapRegions == NULL) { DSErrCode = appMemFullErr; ExitToShell(); } HLock(hHeapRegions); pHeapRegions = (struct _heap_region_ *)(*hHeapRegions); memset(pHeapRegions, 0, sizeof(struct _heap_region_)*_HEAP_REGIONMAX); _heap_region_table_cur = _HEAP_REGIONMAX; } _heap_regionsize = _INITREGIONSZ; /* set region size to 64 Kb */ /* make sure we have enough memory to do initialization */ if ((p = NewPtr(_HEAP_EMPTYLIST_SIZE)) == NULL) { DSErrCode = appMemFullErr; ExitToShell(); } if ((p2 = NewPtr(_heap_regionsize)) == NULL) { DSErrCode = appMemFullErr; ExitToShell(); } if (p) { DisposePtr(p); } if (p2) { DisposePtr(p2); } p = _malloc_base(4); if (p == NULL) { DSErrCode = appMemFullErr; ExitToShell(); } _free_base( p ); /* malloc, then free a block */ _heap_regionsize = oldregionsz; /* restore region size */ }
void * __cdecl _realloc_base (void * pBlock, size_t newsize) { void * pvReturn; size_t origSize = newsize; // if ptr is NULL, call malloc if (pBlock == NULL) return(_malloc_base(newsize)); // if ptr is nonNULL and size is zero, call free and return NULL if (newsize == 0) { _free_base(pBlock); return(NULL); } #ifndef _WIN64 if ( __active_heap == __V6_HEAP ) { PHEADER pHeader; size_t oldsize; for (;;) { pvReturn = NULL; if (newsize <= _HEAP_MAXREQ) { _mlock( _HEAP_LOCK ); __try { // test if current block is in the small-block heap if ((pHeader = __sbh_find_block(pBlock)) != NULL) { // if the new size is not over __sbh_threshold, attempt // to reallocate within the small-block heap if (newsize <= __sbh_threshold) { if (__sbh_resize_block(pHeader, pBlock, (int)newsize)) pvReturn = pBlock; else if ((pvReturn = __sbh_alloc_block((int)newsize)) != NULL) { oldsize = ((PENTRY)((char *)pBlock - sizeof(int)))->sizeFront - 1; memcpy(pvReturn, pBlock, __min(oldsize, newsize)); // headers may have moved, get pHeader again pHeader = __sbh_find_block(pBlock); __sbh_free_block(pHeader, pBlock); } } // If the reallocation has not been (successfully) // performed in the small-block heap, try to allocate // a new block with HeapAlloc. if (pvReturn == NULL) { if (newsize == 0) newsize = 1; newsize = (newsize + BYTES_PER_PARA - 1) & ~(BYTES_PER_PARA - 1); if ((pvReturn = HeapAlloc(_crtheap, 0, newsize)) != NULL) { oldsize = ((PENTRY)((char *)pBlock - sizeof(int)))->sizeFront - 1; memcpy(pvReturn, pBlock, __min(oldsize, newsize)); __sbh_free_block(pHeader, pBlock); } } } } __finally { _munlock( _HEAP_LOCK ); } // the current block is NOT in the small block heap iff pHeader // is NULL if ( pHeader == NULL ) { if (newsize == 0) newsize = 1; newsize = (newsize + BYTES_PER_PARA - 1) & ~(BYTES_PER_PARA - 1); pvReturn = HeapReAlloc(_crtheap, 0, pBlock, newsize); } } else /* newsize > _HEAP_MAXREQ */ {