std::set_new_handler 如何提供更多内存
How does std::set_new_handler make more memory available?
From std::set_new_handler
new-handler 函数是每当内存分配尝试失败时由分配函数调用的函数。它的预期目的是以下三件事之一:
- 提供更多可用内存 终止
- 程序(例如,通过调用 std::终止) 抛出类型为 std::bad_alloc
- 或派生自 std::bad_alloc 的异常
以下重载会保证什么吗?
void * operator new(std::size_t size) throw(std::bad_alloc){
while(true) {
void* pMem = malloc(size);
if(pMem)
return pMem;
std::new_handler Handler = std::set_new_handler(0);
std::set_new_handler(Handler);
if(Handler)
(*Handler)();
else
throw bad_alloc();
}
}
std::set_new_handler
不使内存可用,它会设置分配失败时使用的新处理程序函数。
用户定义的 new-handler 函数可能能够提供更多可用内存,例如通过清除内存缓存或销毁一些不再需要的对象。 默认的 new-handler 不这样做,它是一个空指针,因此分配内存失败只会引发异常,因为标准库无法知道程序中可能不再需要哪些对象。 如果您编写自己的新处理程序,则可能能够根据您对程序及其要求的了解将一些内存返回给系统。
下面是一个工作示例,说明了自定义新处理程序的功能。
#include <iostream>
#include <new>
/// buffer to be allocated after custom new handler has been installed
char* g_pSafetyBuffer = NULL;
/// exceptional one time release of a global reserve
void my_new_handler()
{
if (g_pSafetyBuffer) {
delete [] g_pSafetyBuffer;
g_pSafetyBuffer = NULL;
std::cout << "[Free some pre-allocated memory]";
return;
}
std::cout << "[No memory to free, throw bad_alloc]";
throw std::bad_alloc();
}
/// illustrates how a custom new handler may work
int main()
{
enum { MEM_CHUNK_SIZE = 1000*1000 }; // adjust according to your system
std::set_new_handler(my_new_handler);
g_pSafetyBuffer = new char[801*MEM_CHUNK_SIZE];
try {
while (true) {
std::cout << "Trying another new... ";
new char[200*MEM_CHUNK_SIZE];
std::cout << " ...succeeded.n";
}
} catch (const std::bad_alloc& e) {
std::cout << " ...failed.n";
}
return 0;
}
我不建议演示生产代码的策略,它可能太重而无法预测,在调用一次new_handler后将成功多少分配。我在我的系统上观察到一些成功的分配(玩弄数字看看你的会发生什么)。下面是一个可能的输出:
Trying another new... ...succeeded.
Trying another new... ...succeeded.
Trying another new... ...succeeded.
Trying another new... ...succeeded.
Trying another new... ...succeeded.
Trying another new... [Free some pre-allocated memory] ...succeeded.
Trying another new... ...succeeded.
Trying another new... ...succeeded.
Trying another new... ...succeeded.
Trying another new... [No memory to free, throw bad_alloc] ...failed.
Process returned 0 (0x0) execution time : 0.046 s
Press any key to continue.
相反,从我的角度来看,发布安全缓冲区仅用于以安全的方式终止程序。即使是正确的异常处理也需要内存,如果没有足够的可用内存,则调用abort()
(正如我最近了解到的那样)。
相关文章:
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 在C++中释放内存期间,迭代器与指针有何不同
- Linux承诺的内存比它所能提供的要多
- std::p romise::set_value() 和 std::future::wait() 是否提供内存围栏?
- 无论代码长度如何,以下代码的内存要求有何不同?
- 如何释放为指针变量本身提供的内存?
- C++ 友元函数在内存位置上有何不同?
- 我可以在 Boost.Spirit.Qi 中向列表运算符 (%) 提供内存分配提示吗?
- C 内存模型是否提供了有关构造函数操作的保证
- 指向对象的内存位置的指针已在程序中删除,但仍提供正确答案而不是垃圾值
- 为什么C 标准专门为具有不同访问说明符的类数据成员的内存布局提供了余地
- GlobalMemoryStatusEx() 提供的总虚拟内存为 127 TB
- 为函数设计接口时,强制用户(客户端)提供内存区域 >= 所需大小。怎么做,是好是坏?
- 在DLL中分配内存并将其指针提供给客户端应用程序,这是不是一种糟糕的做法
- 调整 C++ std/boost iostream 以提供对内存块的循环写入
- 结构PROCESS_MEMORY_COUNTERS哪个成员提供当前使用的内存
- C#提供免费的原生C++内存
- "acquire" 和"consume"内存顺序有何不同,何时"consume"可取?
- 在没有 new 关键字的情况下初始化C++对象的内存从何而来
- 在c++中声明类时使用私有访问说明符在内存级别提供了什么保护