Overriding memory allocator in MSVC++

南楼画角 提交于 2019-12-23 14:59:36

问题


While Microsoft standard runtime provides debugging version of allocation functions, it does not really work, because you are not supposed to use naked new in C++ code, so the instrumentation points to standard library, or nowhere because standard library can't be instrumented anyway.

Now I have code that can produce (and record) backtraces of allocations and I also used DUMA. However attempts at replacing the allocation functions broke when we used streams, because streambuf calls to some debug variant and does so inconsistently between new and delete.

So does anybody have experience with replacing allocator, by overriding the functions, not ugly preprocessor tricks, in Microsoft standard runtime? I suspect it involves avoiding the debug allocator, but I want to keep the _DEBUG define for obvious reasons (a lot more debug code depends on it).

Note: we are currently stuck with Visual C++ 9.0 (Visual Studio 2008).

Edit: Avoiding the debug allocator is unlikely to be an option, because the C++ standard library needs to have consistent definitions of new and delete between the functions and instantiations compiled to the library and the instantiations generated in user code since allocation might be done by one and release by the other. That by the way means that defining static inline variants in force-included header is unlikely to cut it.

Edit2: It's not possible with dynamic linking, because Windows bind symbols from specific DLLs, so there is no way to override them at link-time. But we don't need dynamic linking and don't use it because the primary target is WinCE and static linking is default there.


回答1:


Here's how we do it (with jemalloc, but any other allocator is possible):

  1. Compile the custom memory allocator separately as a C static library.
  2. Link your C++ application with the custom allocator library.
  3. Override operators new and delete in your C++ application to invoke the custom allocator.

Notes:

  • The custom allocator must to be written in C, not C++.
  • It is not possible to ensure sufficiently early initialization of the allocator unless it resides in a separate library.
  • Overriding malloc and free is also possible but a lot harder in MSVC, because those are not "weakly"-linked, and because there are a lot of custom variants in MSVC (for example using the /FORCE:MULTIPLE linker flag).

Sample code:

void* operator new(size_t size)
{
  void* ptr = my_malloc(size);
  if (ptr)
    return ptr;
  else
    throw std::bad_alloc();
}

void* operator new[](size_t size)
{
  void* ptr = my_malloc(size);
  if (ptr)
    return ptr;
  else
    throw std::bad_alloc();
}

void* operator new(size_t size, const std::nothrow_t&) throw()
{
  return my_malloc(size);
}

void* operator new[](size_t size, const std::nothrow_t&) throw()
{
  return my_malloc(size);
}

void operator delete(void* pointer) throw()
{
  my_free(pointer);
}

void operator delete[](void* pointer) throw()
{
  my_free(pointer);
}

void operator delete(void* pointer, const std::nothrow_t&) throw()
{
  my_free(pointer);
}

void operator delete[](void* pointer, const std::nothrow_t&) throw()
{
  my_free(pointer);
}


来源:https://stackoverflow.com/questions/12815867/overriding-memory-allocator-in-msvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!