0

我重载了新函数,但不幸的是,我从来没有能够执行全局处理程序来请求我的编译器上的更多内存访问。如果我们调用全局处理程序来请求更多内存,我也不明白下面的代码片段是如何分配给 P 的。

如果有人能对此有所了解,我将不胜感激

void * Pool:: operator new ( size_t size ) throw( const char *)
{
    int n=0;
    while(1)
    {
        void *p = malloc (100000000L);
        if(p==0)
        {
            new_handler ghd= set_new_handler(0);//deinstall curent handler
            set_new_handler(ghd);// install global handler for more memory access
            if(ghd)
                (*ghd)();
            else 
                throw "out of memory exception";
        }
        else
        {
            return p;
        }
    }
}
4

2 回答 2

0

这里有两件事要讨论,第一是使用new_handler,第二是重载operator new

set_new_handler()

当你想使用new_handler时,你必须注册它。这通常是进入main()后要做的第一件事。处理程序也应由您提供。

#include <iostream>
#include <new>

void noMemory() throw()
{
  std::cout << "no memory" << std::endl;
  exit(-1);
}

int main()
{
  set_new_handler(noMemory);
  // this will probably fail and noMemory() will be called
  char *c = new char[100000000L];
  std::cout << "end" << std::endl;
}

当无法分配内存时,将调用您注册的处理程序,并且您有机会释放一些内存。当处理程序返回时,operator new将再次尝试分配您请求的内存量。

新操作员

默认运算符 new的结构与您介绍的类似。从new_handler的角度来看,重要的部分是while(1)循环,因为它负责在调用new_handler之后尝试获取内存。

这个while(1)循环有两种方法:

  • 得到一个有效的指针
  • 抛出异常

当你提供一个new_handler时,你必须牢记这一点,因为如果你不能做任何事情来释放内存,你应该卸载处理程序(或终止或抛出异常),否则你可能会陷入无限循环。

我想在你的代码中省略参数大小只是为了测试目的。

另请参阅Scott Meyers 的 Effective C++ Item 7了解详情。由于 operator new 即使参数 size = 0 也必须返回一个有效指针,所以在operator new中要做的第一件事应该是将 size 覆盖为 1,以防用户想要分配 0 个字节。这个技巧很简单而且相当有效。

于 2013-03-04T11:20:06.543 回答
0

要产生任何效果,程序的某些其他部分必须以前安装了全局处理程序。该处理程序还必须在调用处理程序时释放某种内存(可能是一些可以丢弃的缓冲区或缓存)。

默认的 new_handler 只是一个空指针,因此您的代码很可能最终会抛出异常。

此外,我会抛出一个bad_alloc异常以与其他operator new重载保持一致。

于 2013-03-04T09:40:01.740 回答