1. 替换标准库提供的operator new或operator delete通常基于以下三个理由:

    1). 用来检测运行上的错误.将"new 所得内存"delete掉却不幸失败会导致内存泄露,多次对同一块"new所得内存"施行delete会导致未定义行为,如果让operator new持有一串动态分配所得地址,而operator delete将地址从中移走,就可以很容易检测出上述错误;各式各样的变成错误会导致数据"overruns"(写入点在分配区块末端之后)或"underruns"(写入点在分配区块起点之前),如果自定义一个operator news并超额分配内存,使额外空间放置特定的byte patterns(即签名,signatures),而operator delete检车上述签名是否原封不动,从而判断是否发生overrun或underrun并志记那个事实以及进行非法操作的指针.

    2). 为了强化效能.标准库所提供的operator new和operator delete主要用于一般目的——它们既可被长时间程序(网页服务器,web server等)接受,也可被执行时间小于一秒的程序接受;它们必须处理一系列需求,包括大块内存,小块内存,大小混合内存;它们必须接纳各种分配形态,范围从程序存活期间的少量区块动态分配,到大数量短命对象的持续分配和归还;它们还必须考虑破碎问题,这最终会导致程序无法满足大区快把内存要求.

    由于对内存管理器的要求多种多样,因此标准库所提供的operator news和operator deletes采取中庸之道.因此如果对自己程序的动态内存运行形态有深刻的了解,就会发现定制版的operator new和operator delete性能胜过缺省版本.

    3). 为了收集使用上的统计数据.自行定义operator new和operator delete可以帮助收集软件内存区块大小分布,寿命分布,内存归还次序,最大动态分配量等信息.

2. 以下是一个初阶段global operator new的例子,它能够促进并协助检测"overruns"和"underruns":

struct const int signature=0xDEADBEEF;
typedef unsigned char Byte;
//这段代码还有若干小错误,详下
void* operator new(std::size_t size) throw(std::bad_alloc){
    using namespace std;
    size_t realSize=size+2+sizeof(int);
    void* pMem=malloc(realSize);
    if(!pMem)
        throw bad_alloc();
    *(static_cast<int*>(pMem))=signatrue;
    *(reinterpret_cast<int*>(static_cast<Byte*>(pMem)+realSize-sizeof(int)))=signature;
    return static_cast<Byte*>(pMem)+sizeof(int);
}
View Code

相关文章: