MST

星途 面试题库

面试题:C++中delete []在多线程环境下的使用及潜在问题

在多线程环境中使用delete []操作释放动态分配的数组内存时,可能会遇到哪些问题?如何避免这些问题?请结合线程同步机制(如互斥锁、原子操作等),设计一个安全的多线程环境下使用delete []释放数组内存的方案,并给出详细的代码实现。
36.9万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

可能遇到的问题

  1. 竞态条件:多个线程同时尝试释放同一块数组内存,会导致未定义行为,比如重复释放内存,程序崩溃。
  2. 内存泄漏:由于竞态条件,可能部分线程认为已经释放了内存,而实际未释放,导致内存泄漏。

避免问题的方法

  1. 使用互斥锁:通过互斥锁来保护对delete []操作的访问,确保同一时间只有一个线程能执行释放内存的操作。
  2. 原子引用计数:使用原子操作实现引用计数,当引用计数为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时释放内存。