重写这两个操作符, 插入打印语句,可获得调用地址。代码如下:
#include <Windows.h>
#include <iostream>
#include <stdlib.h>
#include <vcruntime_new.h>
#include <vcruntime_exception.h>
#include <xmemory>
#pragma comment(linker, "/ThrowingNew")
CRITICAL_SECTION cs;
bool bArray = false;
void doneit(void* addr, bool alloc)
{
if (alloc)
{
std::cout << "alloc " << std::hex << addr << std::endl;
std::cout << "--------" << std::endl;
return;
}
std::cout << "free " << std::hex << addr << std::endl;
}
void* __CRTDECL operator new(size_t const size)
{
::EnterCriticalSection(&cs);
if (!bArray)
{
#ifndef _M_IX86
__int64* p = &size;
#else
int* p = (int*)&size;
#endif
p--;
std::cout << "new addr " << std::hex << *p << std::endl;
}
bArray = false;
::LeaveCriticalSection(&cs);
for (;;)
{
if (void* const block = malloc(size))
{
doneit(block, true);
return block;
}
if (_callnewh(size) == 0)
{
if (size == SIZE_MAX)
{
throw std::exception("bad alloc, SIZE_MAX");
}
else
{
throw std::exception("bad alloc");
}
}
}
}
void __CRTDECL operator delete(void* const block) noexcept
{
doneit(block, false);
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK);
#else
free(block);
#endif
}
void* __CRTDECL operator new[](size_t const size)
{
::EnterCriticalSection(&cs);
#ifndef _M_IX86
__int64* p = &size;
#else
int* p = (int*)&size;
#endif
p--;
std::cout << "new[] addr " << std::hex << *p << std::endl;
bArray = true;
::LeaveCriticalSection(&cs);
return operator new(size);
}
#define SUCCESS 0
int main()
{
::InitializeCriticalSection(&cs);
int ret = SUCCESS;
int* p = new int[32];
if (!p)
ret |= 1;
char* ch = new char;
if (!ch)
ret |= 2;
if (!(ret & 1))
{
delete[]p;
p = NULL;
}
if (!(ret & 2))
{
delete ch;
ch = NULL;
}
::DeleteCriticalSection(&cs);
return ret;
}
运行结果如下, 地址正确: