面试题答案
一键面试资源未释放情况
- 内存资源:在线程函数里申请的堆内存(如使用
new
关键字或malloc
函数申请的内存),若线程崩溃,这部分堆内存无法被正常释放,导致内存泄漏。因为线程异常终止时,不会自动调用delete
(对应new
)或free
(对应malloc
)来释放申请的内存。 - 文件资源:打开的文件描述符不会自动关闭。文件处于打开状态,但程序已崩溃,没有机会执行关闭文件的操作(如
fclose
或close
函数),这会导致文件资源未释放。在某些系统中,可能会影响其他程序对该文件的访问,并且可能导致文件系统资源占用。
避免资源泄漏的方法
- 内存资源:
- 智能指针:使用C++ 标准库中的智能指针(
std::unique_ptr
、std::shared_ptr
等)来管理堆内存。智能指针利用RAII(Resource Acquisition Is Initialization)机制,在对象的构造函数中获取资源(如申请内存),在析构函数中释放资源(如调用delete
)。当智能指针超出作用域或线程正常结束时,会自动释放其所管理的内存。例如:
- 智能指针:使用C++ 标准库中的智能指针(
#include <memory>
void threadFunction() {
std::unique_ptr<int> ptr(new int(10));
// 线程函数其他代码
}
- **容器**:对于动态数组,可以使用`std::vector`等容器。容器同样基于RAII机制,会在其析构时自动释放内部元素所占用的内存。
2. 文件资源: - RAII封装:可以将文件操作封装在一个类中,利用RAII机制管理文件资源。在类的构造函数中打开文件,在析构函数中关闭文件。例如:
#include <iostream>
#include <fstream>
class FileGuard {
public:
FileGuard(const std::string& filename) : file(filename) {
if (!file) {
throw std::runtime_error("Failed to open file");
}
}
~FileGuard() {
file.close();
}
std::ofstream& getFile() {
return file;
}
private:
std::ofstream file;
};
void threadFunction() {
try {
FileGuard fileGuard("test.txt");
std::ofstream& file = fileGuard.getFile();
file << "Some data";
} catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
}
}
- **RAII 工具类**:C++ 标准库中也有`std::ifstream`、`std::ofstream`等文件流类,它们在析构时会自动关闭文件,所以在使用文件流对象时,只要确保它们在合适的作用域内正常析构,就能避免文件资源泄漏。