面试题答案
一键面试可能遇到的问题
- 竞态条件:多个线程同时尝试释放同一块数组内存,会导致未定义行为,比如重复释放内存,程序崩溃。
- 内存泄漏:由于竞态条件,可能部分线程认为已经释放了内存,而实际未释放,导致内存泄漏。
避免问题的方法
- 使用互斥锁:通过互斥锁来保护对
delete []
操作的访问,确保同一时间只有一个线程能执行释放内存的操作。 - 原子引用计数:使用原子操作实现引用计数,当引用计数为0时,安全地释放内存。
基于互斥锁的方案代码实现(C++)
#include <iostream>
#include <mutex>
#include <thread>
std::mutex mtx;
int* arrayToDelete = nullptr;
void deleteArray() {
std::lock_guard<std::mutex> lock(mtx);
if (arrayToDelete != nullptr) {
delete[] arrayToDelete;
arrayToDelete = nullptr;
}
}
int main() {
arrayToDelete = new int[10];
std::thread t1(deleteArray);
std::thread t2(deleteArray);
t1.join();
t2.join();
return 0;
}
基于原子引用计数的方案代码实现(C++)
#include <iostream>
#include <memory>
#include <thread>
#include <atomic>
std::atomic<int> refCount(0);
int* arrayToDelete = nullptr;
void releaseArray() {
if (refCount.fetch_sub(1) == 1) {
delete[] arrayToDelete;
arrayToDelete = nullptr;
}
}
void addReference() {
refCount.fetch_add(1);
}
int main() {
arrayToDelete = new int[10];
addReference();
std::thread t1(releaseArray);
std::thread t2(releaseArray);
t1.join();
t2.join();
return 0;
}
在上述基于互斥锁的代码中,std::lock_guard
在构造时自动锁定互斥锁,在析构时自动解锁,确保delete []
操作的线程安全。基于原子引用计数的代码中,std::atomic<int>
保证引用计数操作的原子性,当引用计数减为0时释放内存。