C++中new默认抛出std::bad_alloc异常以强制处理内存分配失败,体现RAII和异常安全设计哲学;而new (std::nothrow)返回nullptr,适用于需避免异常或精细控制错误处理的场景,如嵌入式系统或高并发服务,但要求手动检查指针。

在C++中,
new
std::bad_alloc
new (std::nothrow)
nullptr
C++的
new
std::bad_alloc
然而,C++也提供了一个替代方案:
new (std::nothrow)
nullptr
malloc
new
这背后其实是C++设计哲学的一个核心体现,尤其是与RAII(Resource Acquisition Is Initialization)原则和异常安全紧密相关。当我第一次深入理解C++的异常机制时,就觉得这种设计非常巧妙。
立即学习“C++免费学习笔记(深入)”;
默认抛出
std::bad_alloc
new
nullptr
new
异常机制则将错误处理逻辑与正常业务逻辑分离开来。当
new
catch
new (std::nothrow)
虽然默认抛出异常是主流且推荐的做法,但
new (std::nothrow)
一个典型的场景是资源受限的嵌入式系统。在这些系统中,内存往往非常宝贵,而且异常处理的开销可能无法接受。如果内存分配失败,程序可能需要尝试一些降级操作,而不是直接崩溃。例如,一个图像处理程序可能在内存不足时选择处理更小尺寸的图像,或者直接跳过当前帧。在这种情况下,
new (std::nothrow)
nullptr
nullptr
另一个例子是大型、长时间运行的服务。有时,一个服务可能需要处理大量并发请求,其中某些请求可能需要分配大量内存。如果每次内存分配失败都抛出异常,并且这个异常没有被恰当捕获和处理,可能会导致整个服务崩溃。使用
new (std::nothrow)
此外,当与遗留C风格代码或API交互时,
new (std::nothrow)
malloc
new (std::nothrow)
nullptr
处理内存分配失败,无论是通过异常还是空指针,都需要一套清晰的策略。我通常会根据项目的具体需求和C++标准库的特性来选择最合适的方案。
对于std::bad_alloc
main
try-catch
std::bad_alloc
new
try-catch
#include <iostream>
#include <vector>
#include <new> // For std::bad_alloc
void allocate_large_data() {
// 尝试分配大量内存
std::vector<int>* large_vec = nullptr;
try {
large_vec = new std::vector<int>(1024 * 1024 * 1024 / sizeof(int)); // 1GB
std::cout << "Successfully allocated large vector." << std::endl;
// ... 使用 large_vec ...
delete large_vec;
} catch (const std::bad_alloc& e) {
std::cerr << "Caught std::bad_alloc in allocate_large_data: " << e.what() << std::endl;
// 这里可以进行一些局部清理或日志记录
if (large_vec) { // 确保即使分配失败,也处理可能的半构造对象(虽然bad_alloc通常在构造前)
delete large_vec;
}
throw; // 重新抛出,让上层处理
}
}
int main() {
try {
allocate_large_data();
} catch (const std::bad_alloc& e) {
std::cerr << "Global handler: Failed to allocate memory: " << e.what() << std::endl;
// 在这里进行全局的错误处理,例如记录日志,向用户显示错误消息,然后退出
return 1;
} catch (const std::exception& e) {
std::cerr << "Global handler: An unexpected error occurred: " << e.what() << std::endl;
return 1;
}
return 0;
}对于new (std::nothrow)
nullptr
#include <iostream>
#include <memory> // For std::unique_ptr
int* create_int_array(size_t size) {
int* arr = new (std::nothrow) int[size];
if (arr == nullptr) {
std::cerr << "Failed to allocate " << size << " integers. Returning nullptr." << std::endl;
// 可以返回一个错误码,或者抛出一个自定义异常(如果需要)
}
return arr;
}
int main() {
size_t large_size = 1024 * 1024 * 1024 / sizeof(int); // 1GB
std::unique_ptr<int[]> my_array(create_int_array(large_size)); // 使用智能指针管理
if (my_array) {
std::cout << "Successfully allocated array with nothrow." << std::endl;
// ... 使用 my_array ...
} else {
std::cout << "Array allocation failed with nothrow. Program can continue." << std::endl;
// 可以尝试其他策略,比如使用更小的数组,或者从磁盘加载数据
}
size_t small_size = 10;
std::unique_ptr<int[]> small_array(create_int_array(small_size));
if (small_array) {
std::cout << "Successfully allocated small array." << std::endl;
}
return 0;
}此外,无论采用哪种方式,内存管理工具和技术都是不可或缺的。使用
std::unique_ptr
std::shared_ptr
new
以上就是C++中new失败时是抛出异常还是返回空指针的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号