C++ 使用带有特征库的自定义新处理程序

C++ 使用带有特征库的自定义新处理程序,c++,new-operator,eigen,C++,New Operator,Eigen,我正在尝试使用一个自定义的新处理程序来响应使用库的程序中的内存不足错误 当我解算一个实例时,我会缓存结果(一个大的动态大小向量),因此如果我需要再次解算该实例,我已经得到了结果。过一段时间后,可能会发生缓存过多实例的情况,因此计算期间内存不足。在这种情况下,我会清空缓存(或者最好删除一些实例) 我想到的最简单的方法是使用一个全局变量std::map cache,并安装一个新的处理程序来清空它(除非它已经是空的,否则它会使用默认的处理程序)。这样,当分配失败时,我的处理程序会释放一些内存并返回,因

我正在尝试使用一个自定义的新处理程序来响应使用库的程序中的内存不足错误

当我解算一个实例时,我会缓存结果(一个大的动态大小向量),因此如果我需要再次解算该实例,我已经得到了结果。过一段时间后,可能会发生缓存过多实例的情况,因此计算期间内存不足。在这种情况下,我会清空缓存(或者最好删除一些实例)

我想到的最简单的方法是使用一个全局变量
std::map cache
,并安装一个新的处理程序来清空它(除非它已经是空的,否则它会使用默认的处理程序)。这样,当分配失败时,我的处理程序会释放一些内存并返回,因此会再次尝试分配内存

然而,似乎从未调用过这样的处理程序,而是总是抛出一个
std::bad_alloc
异常

我试过这个例子。使用
std::vector
时,正确调用自定义处理程序,并打印“内存分配失败,终止”。使用
Eigen::VectorXi
时,我只得到一个
std::bad_alloc
异常

#include <Eigen/Dense>

#include <iostream>
#include <vector>
#include <new>

void handler()
{
    std::cout << "Memory allocation failed, terminating\n";
    std::set_new_handler(nullptr);
}

int main()
{
    std::set_new_handler(handler);
    try {
        while(true) {
            const unsigned long int Size = 100000000ul;

            // Either one of the following:

            // new Eigen::VectorXi(Size);
            new std::vector<int>(Size);
        }
    } catch (const std::bad_alloc & e) {
        std::cout << e.what() << '\n';
    }
}
#包括
#包括
#包括
#包括
void处理程序()
{

std::cout查看egen源代码中的这个文件:egen/src/Core/util/Memory.h,看看egen在这个部门做了什么。IIRC我们在分配失败时会显式地抛出bad_alloc。如果我们需要更改某些内容,请随时写信给邮件列表。

多亏了Benoit Jacob的建议,我找到了egen分配的部分内存。该函数是在
Eigen/src/Core/util/memory.h
中定义的
aligned\u malloc()

我发现了这一点,并相应地修改了函数
aligned\u malloc()

inline void* aligned_malloc(size_t size)
{
  check_that_malloc_is_allowed();

  while (true) {
    void *result;
    #if !EIGEN_ALIGN
      result = std::malloc(size);
    #elif EIGEN_MALLOC_ALREADY_ALIGNED
      result = std::malloc(size);
    #elif EIGEN_HAS_POSIX_MEMALIGN
      if(posix_memalign(&result, 16, size)) result = 0;
    #elif EIGEN_HAS_MM_MALLOC
      result = _mm_malloc(size, 16);
    #elif (defined _MSC_VER)
      result = _aligned_malloc(size, 16);
    #else
      result = handmade_aligned_malloc(size);
    #endif

    if(result || !size) {
      return result;
    }

    std::new_handler currentHandler = std::set_new_handler(0);
    std::set_new_handler(currentHandler);

    if (currentHandler) {
      currentHandler();
    } else {
      throw_std_bad_alloc();
    }
  }
}
现在,当分配失败时,内存处理程序被正确地调用(可能还需要修改其他分配函数,但它们似乎都由
aligned_malloc()
包装,因此签入该函数可能涵盖所有内容)


但是在这一点上,我不确定Eigen是否应该尊重新的处理程序:它从
malloc()
获取内存,它不使用异常,但会通知
malloc()
失败通过抛出
std::bad_alloc

谢谢你的建议,我成功地实现了我想要的行为。我发布了一个新的答案和详细信息。