覆盖MSVC ++中的内存分配器 [英] Overriding memory allocator in MSVC++

查看:138
本文介绍了覆盖MSVC ++中的内存分配器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管Microsoft标准运行时提供了分配功能的调试版本,但它实际上不起作用,因为您不应该在C ++代码中使用裸露的新内容,因此检测指向标准库,否则就指向标准库,因为标准库不能反正装备了.

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.

现在,我拥有可以产生(并记录)分配回溯的代码,并且我还使用了 DUMA .但是,当我们使用流时,替换分配函数的尝试失败了,因为streambuf调用某些调试变量,并且new和delete之间的用法不一致.

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.

那么,有人在Microsoft标准运行时中通过重写功能而不是丑陋的预处理器技巧来代替分配器吗?我怀疑它涉及到避免调试分配器,但是出于明显的原因,我想保留_DEBUG定义(更多的调试代码取决于它).

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).

注意:目前,我们只能使用Visual C ++ 9.0(Visual Studio 2008).

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

避免调试分配器不太可能是一种选择,因为C ++标准库需要对new进行一致的定义,并在编译到该库的函数和实例与用户代码中生成的实例之间进行删除,因为分配可能是由一个人完成,由另一个人释放.顺便说一句,这意味着在包含力的标头中定义静态内联变体不太可能削减它.

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:动态链接是不可能的,因为Windows绑定来自特定DLL的符号,因此无法在链接时覆盖它们.但是我们不需要动态链接,也不需要使用动态链接,因为主要目标是WinCE,而静态链接是默认链接.

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.

推荐答案

这是我们的操作方法(使用jemalloc,但也可以使用其他分配器):

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

  1. 将自定义内存分配器分别编译为C静态库.
  2. 将您的C ++应用程序与自定义分配器库链接.
  3. 在C ++应用程序中重写运算符newdelete来调用自定义分配器.
  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.

注意:

  • 自定义分配器必须用C而不是C ++编写.
  • 除非分配器位于单独的库中,否则无法确保足够早地对其进行初始化.
  • 也可以覆盖mallocfree,但在MSVC中要困难得多,因为它们不是弱"链接的,并且因为MSVC中有很多自定义变体(例如,使用/FORCE:MULTIPLE链接器标志).
  • 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).

示例代码:

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);
}

这篇关于覆盖MSVC ++中的内存分配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆