面试题答案
一键面试基于异常机制处理内存分配失败
在C++中使用new
操作符分配内存时,如果内存分配失败,new
会抛出std::bad_alloc
异常。可以使用try - catch
块来捕获并处理这个异常,示例代码如下:
#include <iostream>
#include <new>
int main() {
try {
int* ptr = new int[1000000000]; // 可能会导致内存分配失败
// 使用分配的内存
delete[] ptr;
} catch (const std::bad_alloc& e) {
std::cerr << "内存分配失败: " << e.what() << std::endl;
}
return 0;
}
与malloc
处理方式相比的优势
- 代码结构清晰:使用
try - catch
块处理异常使得错误处理代码与正常业务逻辑分离,提高了代码的可读性和维护性。在复杂程序中,这种分离能够让开发者更清晰地看到正常流程和异常处理流程。 - 自动资源管理:C++中的智能指针(如
std::unique_ptr
、std::shared_ptr
)结合异常机制,能够在异常抛出时自动释放已分配的资源,避免了资源泄漏。例如:
#include <iostream>
#include <memory>
int main() {
try {
std::unique_ptr<int[]> ptr(new int[1000000000]);
// 使用分配的内存
} catch (const std::bad_alloc& e) {
std::cerr << "内存分配失败: " << e.what() << std::endl;
}
return 0;
}
- 异常传播:异常可以在函数调用栈中向上传播,使得上层调用者可以统一处理不同层次函数中的内存分配失败情况。这样在复杂的函数调用链中,不必在每个可能分配内存的地方都进行繁琐的错误检查。
与malloc
处理方式相比的劣势
- 性能开销:异常机制有一定的性能开销,包括抛出异常时栈展开的时间和空间开销。在对性能要求极高且内存分配操作频繁的场景下,这种开销可能会成为瓶颈。
- 兼容性和可移植性:
malloc
是C语言标准库函数,在C和C++中都广泛支持,并且在不同平台上的行为相对一致。而异常处理机制在一些特殊环境(如嵌入式系统)中可能不被支持或需要额外的配置,降低了可移植性。 - 调试难度:异常抛出的位置可能与实际导致异常的位置相隔较远,在复杂程序中定位问题的难度增加。特别是当异常在多个函数调用间传播时,追踪异常的来源可能变得困难。