首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

不用C和C++的内存分配函数(new,malloc.),如何样实现内存配接器

2012-02-23 
不用C和C++的内存分配函数(new,malloc....),怎么样实现内存配接器不用C和C++的内存分配函数(new,malloc...

不用C和C++的内存分配函数(new,malloc....),怎么样实现内存配接器
不用C和C++的内存分配函数(new,malloc....),怎么样实现内存配接器

????????

怎么办呢??

[解决办法]
那你去阅读malloc代码...
[解决办法]
用GlobalAlloc、、GlobalLock、、GlobalUnlock、GlobalFree这些吧

[解决办法]
楼主就别是一个企业了,这是微软的面试题!

转载的答案如下:

/*** 
*malloc.c - Get a block of memory from the heap 

* Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved. 

*Purpose: 
* Defines the malloc() function. 

*******************************************************************************/ 

#include <cruntime.h> 
#include <malloc.h> 
#include <internal.h> 
#include <mtdll.h> 
#include <dbgint.h> 

#ifdef WINHEAP 
#include <windows.h> 
#include <winheap.h> 
#else /* WINHEAP */ 
#include <heap.h> 
#endif /* WINHEAP */ 


extern int _newmode; /* malloc new() handler mode */ 


/*** 
*void *malloc(size_t size) - Get a block of memory from the heap 

*Purpose: 
* Allocate of block of memory of at least size bytes from the heap and 
* return a pointer to it. 

* Calls the new appropriate new handler (if installed). 

*Entry: 
* size_t size - size of block requested 

*Exit: 
* Success: Pointer to memory block 
* Failure: NULL (or some error value) 

*Uses: 

*Exceptions: 

*******************************************************************************/ 

void * __cdecl _malloc_base (size_t size) 


return _nh_malloc_base(size, _newmode); 



/*** 
*void *_nh_malloc_base(size_t size) - Get a block of memory from the heap 

*Purpose: 
* Allocate of block of memory of at least size bytes from the heap and 
* return a pointer to it. 

* Calls the appropriate new handler (if installed). 

* There are two distinct new handler schemes supported. The 'new' ANSI 
* C++ scheme overrides the 'old' scheme when it is activated. A value of 
* _NOPTH for the 'new' handler indicates that it is inactivated and the 
* 'old' handler is then called. 

*Entry: 
* size_t size - size of block requested 

*Exit: 
* Success: Pointer to memory block 
* Failure: NULL (or some error value) 

*Uses: 

*Exceptions: 

*******************************************************************************/ 

void * __cdecl _nh_malloc_base (size_t size, int nhFlag) 

void * pvReturn; 

// validate size 
if (size > _HEAP_MAXREQ) 
return NULL; 

#ifndef WINHEAP 
/* round requested size */ 
size = _ROUND2(size, _GRANULARITY); 
#endif /* WINHEAP */ 

for (;;) { 

// allocate memory block 
if (size <= _HEAP_MAXREQ) 
pvReturn = _heap_alloc_base(size); 
else 
pvReturn = NULL; 

// if successful allocation, return pointer to memory 
// if new handling turned off altogether, return NULL 

if (pvReturn || nhFlag == 0) 


return pvReturn; 

// call installed new handler 
if (!_callnewh(size)) 
return NULL; 

// new handler was successful -- try to allocate again 



/*** 
*void *_heap_alloc_base(size_t size) - does actual allocation 

*Purpose: 
* Same as malloc() except the new handler is not called. 

*Entry: 
* See malloc 

*Exit: 
* See malloc 

*Exceptions: 

*******************************************************************************/ 

void * __cdecl _heap_alloc_base (size_t size) 


#ifdef WINHEAP 
void * pvReturn; 
#else /* WINHEAP */ 
_PBLKDESC pdesc; 
_PBLKDESC pdesc2; 
#endif /* WINHEAP */ 


#ifdef WINHEAP 

if (size <= __sbh_threshold) 

_mlock(_HEAP_LOCK); 
pvReturn = __sbh_alloc_block(size); 
_munlock(_HEAP_LOCK); 
if (pvReturn) 
return pvReturn; 


if (size == 0) 
size = 1; 
size = (size + BYTES_PER_PARA - 1) & ~(BYTES_PER_PARA - 1); 
return HeapAlloc(_crtheap, 0, size); 


#else /* WINHEAP */ 

/* try to find a big enough free block 
*/ 
if ( (pdesc = _heap_search(size)) == NULL ) 

if ( _heap_grow(size) != -1 ) 

/* try finding a big enough free block again. the 
* success of the call to _heap_grow should guarantee 
* it, but... 
*/ 
if ( (pdesc = _heap_search(size)) == NULL ) 

/* something unexpected, and very bad, has 
* happened. abort! 
*/ 
_heap_abort(); 


else 
return NULL; 


/* carve the block into two pieces (if necessary). the first piece 
* shall be of the exact requested size, marked inuse and returned to 
* the caller. the leftover piece is to be marked free. 
*/ 
if ( _BLKSIZE(pdesc) != size ) { 
/* split up the block and free the leftover piece back to 
* the heap 
*/ 
if ( (pdesc2 = _heap_split_block(pdesc, size)) != NULL ) 
_SET_FREE(pdesc2); 


/* mark pdesc inuse 
*/ 
_SET_INUSE(pdesc); 

/* check proverdesc and reset, if necessary 
*/ 

_heap_desc.proverdesc = pdesc->pnextdesc; 

return( (void *)((char *)_ADDRESS(pdesc) + _HDRSIZE) ); 



/*** 
*_PBLKDESC _heap_split_block(pdesc, newsize) - split a heap allocation block 
* into two allocation blocks 

*Purpose: 
* Split the allocation block described by pdesc into two blocks, the 
* first one being of newsize bytes. 

* Notes: It is caller's responsibilty to set the status (i.e., free 
* or inuse) of the two new blocks, and to check and reset proverdesc 
* if necessary. See Exceptions (below) for additional requirements. 

*Entry: 
* _PBLKDESC pdesc - pointer to the allocation block descriptor 
* size_t newsize - size for the first of the two sub-blocks (i.e., 
* (i.e., newsize == _BLKSIZE(pdesc), on exit) 

*Exit: 
* If successful, return a pointer to the descriptor for the leftover 
* block. 
* Otherwise, return NULL. 

*Exceptions: 
* It is assumed pdesc points to a valid allocation block descriptor and 
* newsize is a valid heap block size as is (i.e., WITHOUT rounding). If 


* either of these of assumption is violated, _heap_split_block() will 
* likely corrupt the heap. Note also that _heap_split_block will simply 
* return to the caller if newsize >= _BLKSIZE(pdesc), on entry. 

*******************************************************************************/ 

_PBLKDESC __cdecl _heap_split_block ( 
REG1 _PBLKDESC pdesc, 
size_t newsize 


REG2 _PBLKDESC pdesc2; 

_ASSERTE(("_heap_split_block: bad pdesc arg", _CHECK_PDESC(pdesc))); 
_ASSERTE(("_heap_split_block: bad newsize arg", _ROUND2(newsize,_GRANULARITY) == newsize)); 

/* carve the block into two pieces (if possible). the first piece 
* is to be exactly newsize bytes. 
*/ 
if ( (_BLKSIZE(pdesc) > newsize) && ((pdesc2 = __getempty()) 
!= NULL) ) 

/* set it up to manage the second piece and link it in to 
* the list 
*/ 
pdesc2->pblock = (void *)((char *)_ADDRESS(pdesc) + newsize + 
_HDRSIZE); 
*(void **)(pdesc2->pblock) = pdesc2; 
pdesc2->pnextdesc = pdesc->pnextdesc; 
pdesc->pnextdesc = pdesc2; 

return pdesc2; 

return NULL; 


#endif /* WINHEAP */

热点排行