MST
星途 面试题库

面试题:C++中const char *p与char * const p类型转换在多线程与内存管理下的综合应用

在一个多线程环境下,有一个线程A不断更新一个char * const的指针指向新分配的内存块(通过new char[]分配),另一个线程B需要读取这些数据并调用一个只接受const char *参数的函数。请设计一个安全高效的机制来处理这种情况,要考虑内存泄漏、数据竞争等问题,用C++代码实现并详细解释你的设计。
28.5万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;
std::unique_ptr<char[]> currentData;
bool dataReady = false;

void threadA() {
    while (true) {
        // 模拟获取新数据
        std::unique_ptr<char[]> newData(new char[100]);
        // 填充数据
        for (int i = 0; i < 100; ++i) {
            newData[i] = 'a' + i % 26;
        }

        {
            std::unique_lock<std::mutex> lock(mtx);
            currentData = std::move(newData);
            dataReady = true;
        }
        cv.notify_one();

        // 模拟其他工作
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

void threadB() {
    while (true) {
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock, [] { return dataReady; });

        const char* dataToProcess = currentData.get();
        // 调用接受const char*参数的函数
        std::cout << "Thread B processing data: ";
        for (int i = 0; i < 100; ++i) {
            std::cout << dataToProcess[i];
        }
        std::cout << std::endl;

        dataReady = false;
    }
}

int main() {
    std::thread a(threadA);
    std::thread b(threadB);

    a.join();
    b.join();

    return 0;
}

设计解释

  1. 数据存储
    • 使用std::unique_ptr<char[]>来管理动态分配的内存,避免内存泄漏。std::unique_ptr在其析构时会自动释放所管理的内存。
  2. 同步机制
    • std::mutex mtx用于保护共享资源currentDatadataReady,防止数据竞争。
    • std::condition_variable cv用于线程间的通信。线程B在cv.wait处等待,直到线程A更新数据并通过cv.notify_one唤醒线程B。
  3. 线程A的工作
    • 线程A不断分配新的内存块,填充数据。
    • 使用std::unique_lock<std::mutex>来锁定互斥量mtx,将newData转移给currentData,并设置dataReadytrue
    • 解锁互斥量并通过cv.notify_one通知线程B数据已准备好。
  4. 线程B的工作
    • 线程B在cv.wait处等待,直到dataReadytrue
    • 锁定互斥量mtx,获取currentData指向的数据并调用接受const char*参数的函数(这里简单地将数据打印出来)。
    • 处理完数据后,将dataReady设为false,解锁互斥量,继续等待下一次数据更新。
  5. 内存管理
    • 由于std::unique_ptr的使用,当currentData被新的数据替换时,旧的数据会自动释放,避免了内存泄漏。同时,在threadAthreadB中,通过互斥量和条件变量的配合,保证了数据的安全访问。