最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++利用對象池優(yōu)化內(nèi)存管理解決MISRA報警的代碼詳解

 更新時間:2025年07月25日 09:10:31   作者:mr.Darker  
本篇詳細講解如何用對象池技術(shù)優(yōu)化C++項目中的內(nèi)存管理,徹底消除new/delete帶來的MISRA報警,兼顧高性能與安全規(guī)范,需要的朋友可以參考下

1. 背景與問題起因

初始需求:

  • 動態(tài)創(chuàng)建/銷毀 AOI 和 Controller 處理器對象
  • 原實現(xiàn)用傳統(tǒng) new / delete
  • 通過工廠函數(shù) CreateProcessor() 分配對象

初始代碼(示意):

IProcessor* CreateAoiProcessor() {
    return new CAoiProcessor();
}

void ReleaseProcessor(IProcessor* pProcessor) {
    delete pProcessor;
}

遇到的問題:

  • MISRA / AUTOSAR 檢查工具報錯:

Rule A18-4-1:Dynamic heap memory allocation shall not be used.

風險點:

  • new/delete 不可控、難追蹤、不可預測(OOM、碎片)
  • 對于嵌入式、工業(yè)控制項目,這是大小禁忌
  • MISRA / AUTOSAR 標準嚴禁使用動態(tài)分配

2. 初步嘗試:對象池(ProcessorObjectPool)設(shè)計

基本思路:

  • 緩存還未被使用的對象,避免重復創(chuàng)建
  • 使用 std::unique_ptr 確保所有權(quán)限獨占
  • 用戶需要手動 Release ,將對象歸還池內(nèi)

優(yōu)點:

  • 消除 new/delete,滿足標準
  • 超高性能,極簡單的內(nèi)存管理
  • 適合靜態(tài)存儲、有限對象數(shù)量場景

缺點:

  • 必須手動 Release,容易忘記
  • 外部用法算是稍復雜

使用場景:

  • 簡單異步性不高的應(yīng)用,如單線編碼器系統(tǒng)
  • 對象使用常性很高,能確保不會忘記 Release 的項目
  • 推薦第一次試測或無需交叉線編程的場景

3. 二次優(yōu)化:shared_ptr + 自定義刪除器版本

核心思路:

  1. 對象池內(nèi)部預分配完整對象,禁止動態(tài)分配
  2. 對外接口選擇 std::shared_ptr,綁定自定義刪除器
  3. 當用戶釋放對象時,并非 delete,而是將對象歸還池內(nèi)

優(yōu)點:

  • 手動釋放的問題全部消失,用戶不需關(guān)心
  • 外部用法極簡單,與普通 shared_ptr 無差
  • 滿足 MISRA / AUTOSAR,依然是靜態(tài)內(nèi)存分配

缺點:

  • 少量的引用計數(shù)跟蹤負擔
  • 但對于當前項目,很值,算中級性能優(yōu)化

使用場景:

  • 對象需要被多個模塊共享、交付或經(jīng)過多級層傳遞的場景
  • 需要自動管理生命周期,避免手動釋放風險
  • 常見于有較復雜邏輯或有多線程跨線使用需求的應(yīng)用

4. 解決過程中的 MISRA / AUTOSAR 報警問題記錄

報警規(guī)則編號報警信息解決方案
A18-4-1禁止動態(tài)內(nèi)存分配(禁止 new/delete)替換為對象池,固定數(shù)組預分配
M6-6-5函數(shù)必須只有一個出口統(tǒng)一 return,避免提前返回
M4-2-1if/else 必須成對補全 else 分支
命名規(guī)范成員變量必須加 m_ 前綴全部重命名為 m_xxx
OOP50-CPP構(gòu)造/析構(gòu)中不能調(diào)用虛函數(shù)移除析構(gòu)中 Stop() 調(diào)用
M12-1-1構(gòu)造/析構(gòu)中禁止訪問對象的動態(tài)類型(虛函數(shù)風險)構(gòu)造函數(shù)內(nèi)只做初始化,不調(diào)虛函數(shù)
命名規(guī)范static 成員必須加 s_ 前綴全部 static 變量改為 s_xxx

5. 整體優(yōu)化成果

  • 代碼質(zhì)量顯著提升
  • 消除全部 MISRA 報警
  • 對象復用,減少內(nèi)存開銷
  • 支持多線程,自動釋放,維護成本降低

6. 最終對比總結(jié)

版本內(nèi)存分配安全性易用性MISRA合規(guī)性
原版 new/delete動態(tài)堆分配容易泄漏簡單但危險不合規(guī)
unique_ptr 對象池版靜態(tài)預分配手動釋放安全一般合規(guī)
shared_ptr 對象池版靜態(tài)預分配自動回收最安全最易用合規(guī)

7. 建議總結(jié)

  • 工業(yè)、嵌入式、MISRA/AUTOSAR 場景下,強烈推薦對象池 + shared_ptr 刪除器方案
  • 適用于所有“對象個數(shù)固定、生命周期可控、性能敏感”的系統(tǒng)

附錄:完整示例代碼(建議放文末)

ProcessorObjectPool.hpp

// unique_ptr 對象池版本源碼
#pragma once

#include <stack>
#include <memory>
#include <mutex>

/**
 * @brief 通用的處理器對象池模板。
 * @tparam T 實際實現(xiàn) IProcessor 的派生類。
 */
template <typename T>
class ProcessorObjectPool {
public:
    using Ptr = std::unique_ptr<T>;

    /**
     * @brief 獲取一個處理器對象。
     * @return 智能指針,包裝了一個 T 類型實例。
     */
    Ptr Acquire();

    /**
     * @brief 回收一個處理器對象。
     * @param pObj 要回收的對象(智能指針)。
     */
    void Release(Ptr pObj);

    /**
     * @brief 獲取對象池的單例實例。
     * @return 靜態(tài)的對象池實例。
     */
    static ProcessorObjectPool<T>& Instance();

private:
    ProcessorObjectPool() = default;
    ~ProcessorObjectPool() = default;

    ProcessorObjectPool(const ProcessorObjectPool&) = delete;
    ProcessorObjectPool& operator=(const ProcessorObjectPool&) = delete;

    std::stack<Ptr> m_pool;
    std::mutex m_mutex;
    static constexpr std::size_t MAX_POOL_SIZE = 64;  ///< 池中最大緩存對象數(shù)量
};

// 模板實現(xiàn)必須包含在頭文件中
#include "ProcessorObjectPool.inl"

//============================================================================================
//============================================================================================

// shared_ptr 對象池版本源碼
#pragma once

#include <array>
#include <memory>
#include <mutex>
#include <bitset>
#include <cstddef>

/**
 * @file ProcessorObjectPool.h
 * @brief 基于靜態(tài)內(nèi)存的對象池模板類,適配 MISRA / AUTOSAR C++。
 * @tparam T 對象類型(必須支持默認構(gòu)造)。
 * @tparam N 對象池大小,最大可同時持有的對象數(shù)量。
 */
template <typename T, std::size_t N>
class ProcessorObjectPool {
public:
    /**
     * @brief 對象指針類型,使用 shared_ptr 包裝,帶自定義回收邏輯。
     */
    using Ptr = std::shared_ptr<T>;

    /**
     * @brief 獲取對象池的單例實例。
     * @return 返回靜態(tài)單例。
     */
    static ProcessorObjectPool& Instance();

    /**
     * @brief 獲取一個可用對象指針。
     * @return 有效 shared_ptr,如果池已滿返回空指針。
     */
    Ptr Acquire();

    /**
     * @brief 回收對象指針(由 shared_ptr 的 deleter 調(diào)用)。
     * @param pObj 需回收的對象指針。
     */
    void Recycle(T* pObj);

private:
    ProcessorObjectPool() = default;
    ~ProcessorObjectPool() = default;

    // 禁止復制與賦值
    ProcessorObjectPool(const ProcessorObjectPool&) = delete;
    ProcessorObjectPool& operator=(const ProcessorObjectPool&) = delete;

    std::array<T, N> m_objects;     ///< 靜態(tài)分配的對象數(shù)組
    std::bitset<N> m_used{};        ///< 標記哪些對象已被占用
    std::mutex m_mutex;             ///< 互斥鎖,保護并發(fā)訪問
};

#include "ProcessorObjectPool.inl"  // 模板實現(xiàn)必須放頭文件中

ProcessorObjectPool.inl

// 這里預留 unique_ptr 對象池版本實現(xiàn)
#pragma once

#include <utility>

template <typename T>
typename ProcessorObjectPool<T>::Ptr ProcessorObjectPool<T>::Acquire() {
    std::lock_guard<std::mutex> lock(m_mutex);
    if (!m_pool.empty()) {
        Ptr obj = std::move(m_pool.top());
        m_pool.pop();
        return obj;
    } else {
        return std::unique_ptr<T>(new T());  // C++14 不能用 make_unique
    }
}

template <typename T>
void ProcessorObjectPool<T>::Release(Ptr pObj) {
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_pool.size() < MAX_POOL_SIZE) {
        m_pool.push(std::move(pObj));
    } else {
        // 超出限制,自動釋放,不入池
    }
}

template <typename T>
ProcessorObjectPool<T>& ProcessorObjectPool<T>::Instance() {
    static ProcessorObjectPool<T> instance;
    return instance;
}

//============================================================================================
//============================================================================================

// 這里預留 shared_ptr 對象池版本實現(xiàn)
#pragma once

/**
 * @brief 獲取單例對象池實例。
 */
template <typename T, std::size_t N>
ProcessorObjectPool<T, N>& ProcessorObjectPool<T, N>::Instance()
{
    static ProcessorObjectPool<T, N> instance;
    return instance;
}

/**
 * @brief 獲取一個可用對象的 shared_ptr。
 *        若池中存在未使用對象,則直接返回;
 *        若全部占用,則返回空 shared_ptr。
 */
template <typename T, std::size_t N>
typename ProcessorObjectPool<T, N>::Ptr ProcessorObjectPool<T, N>::Acquire()
{
    std::lock_guard<std::mutex> lock(m_mutex);

    T* pRaw = nullptr;
    for (std::size_t i = 0; i < N; ++i) {
        if (!m_used[i]) {
            m_used[i] = true;
            pRaw = &m_objects[i];
            break;
        }
    }

    Ptr result;
    if (pRaw != nullptr) {
        // 創(chuàng)建 shared_ptr,附帶回收 deleter
        result = Ptr(pRaw, [](T* p) {
            ProcessorObjectPool<T, N>::Instance().Recycle(p);
        });
    }

    return result;
}

/**
 * @brief 回收一個對象指針回池中。
 * @param pObj 需釋放的對象,必須為池中對象。
 */
template <typename T, std::size_t N>
void ProcessorObjectPool<T, N>::Recycle(T* pObj)
{
    if (nullptr == pObj) {
	    return;
    }

    std::lock_guard<std::mutex> lock(m_mutex);
    const std::ptrdiff_t nIndex = pObj - m_objects.data();
    if ((nIndex >= 0) && (static_cast<std::size_t>(nIndex) < N)) {
        m_used[static_cast<std::size_t>(nIndex)] = false;
        // 注意:對象不會析構(gòu)。若對象含狀態(tài),應(yīng)在 T 內(nèi)部自行 reset()
        pObj->Reset();
    }
}

ProcessorFactory.cpp 舊新對比

// ProcessorFactory 舊源碼
#include "pch.h"
#include "ProcessorFactory.h"

#include "AoiProcessor.h"
#include "ControllerProcessor.h"

extern "C" {
    IProcessor* CreateAoiProcessor() {
        return new CAoiProcessor();
    }

    IProcessor* CreateControllerProcessor() {
        return new CControllerProcessor();
    }

    void ReleaseProcessor(IProcessor* pProcessor) {
        if (pProcessor) {
            delete pProcessor;
        }
    }
}

//============================================================================================
//============================================================================================

// ProcessorFactory 新源碼
#include "pch.h"
#include "ProcessorFactory.h"
#include "AoiProcessor.h"
#include "ControllerProcessor.h"
#include "ProcessorObjectPool.h"

// 使用靜態(tài)池管理對象(不使用 new/delete)
using AoiProcessorPool = ProcessorObjectPool<CAoiProcessor, 32>;
using CtrlProcessorPool = ProcessorObjectPool<CControllerProcessor, 32>;

// 內(nèi)部共享引用池,避免 shared_ptr 提前析構(gòu)
static std::vector<std::shared_ptr<IProcessor>> s_processorRefs;
static std::mutex s_mutex;

extern "C" {
    IProcessor* CreateProcessor(int nType) {
        std::shared_ptr<IProcessor> sp;
        IProcessor* pRaw = nullptr;

        if (nType == 0) {
            sp = AoiProcessorPool::Instance().Acquire();
        }
        else if (nType == 1) {
            sp = CtrlProcessorPool::Instance().Acquire();
        }
        else {
            sp = nullptr;
		}

        if (sp) {
            pRaw = sp.get();
            std::lock_guard<std::mutex> lock(s_mutex);
            s_processorRefs.emplace_back(std::move(sp));
        }

        return pRaw;
    }

    void ReleaseProcessor(IProcessor* pProcessor) {
        if (pProcessor == nullptr) {
            return;
        }

        std::lock_guard<std::mutex> lock(s_mutex);
        auto it = std::remove_if(s_processorRefs.begin(), s_processorRefs.end(), [=](const std::shared_ptr<IProcessor>& ptr) {
        	return ptr.get() == pProcessor;
        });
        s_processorRefs.erase(it, s_processorRefs.end());
    }
}

以上就是C++利用對象池優(yōu)化內(nèi)存管理解決MISRA報警的代碼詳解的詳細內(nèi)容,更多關(guān)于C++對象池優(yōu)化內(nèi)存管理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • c++使用 std::string 存儲二進制數(shù)據(jù)

    c++使用 std::string 存儲二進制數(shù)據(jù)

    std::string 可安全存儲二進制數(shù)據(jù),具備自動內(nèi)存管理和豐富操作接口,通過直接賦值、文件讀寫等方式可處理任意字節(jié)值,下面就來介紹一下如何使用,感興趣的可以了解一下
    2026-01-01
  • C++編程中隊內(nèi)聯(lián)函數(shù)的理解和使用

    C++編程中隊內(nèi)聯(lián)函數(shù)的理解和使用

    這篇文章主要介紹了C++編程中隊內(nèi)聯(lián)函數(shù)的理解和使用,簡單舉例講解了inline關(guān)鍵字引出的內(nèi)聯(lián)函數(shù)的相關(guān)知識,需要的朋友可以參考下
    2016-01-01
  • C++無痛實現(xiàn)日期類的示例代碼

    C++無痛實現(xiàn)日期類的示例代碼

    凡是要寫類必須要提到六大默認成員(六位大爺):構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、賦值重載函數(shù)、取地址重載函數(shù)(包括const對象和普通對象);那么這次的日期類又需要伺候哪幾位大爺呢?本文就來詳細說說
    2022-10-10
  • C語言實現(xiàn)紅黑樹詳細步驟+代碼

    C語言實現(xiàn)紅黑樹詳細步驟+代碼

    大家好,本篇文章主要講的是C語言實現(xiàn)紅黑樹詳細步驟+代碼,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • c語言動態(tài)內(nèi)存分配知識點及實例

    c語言動態(tài)內(nèi)存分配知識點及實例

    在本篇文章里小編給大家整理的是關(guān)于c語言動態(tài)內(nèi)存分配知識點及實例,需要的朋友們可以學習下。
    2020-03-03
  • C++中常見的六種內(nèi)存序

    C++中常見的六種內(nèi)存序

    內(nèi)存序是多線程編程中控制原子操作內(nèi)存可見性和執(zhí)行順序的機制,本文主要介紹了C++中常見的六種內(nèi)存序,具有一定的參考價值,感興趣的可以了解一下
    2025-06-06
  • C++內(nèi)存四區(qū)之代碼區(qū)、全局區(qū)、棧區(qū)和堆區(qū)

    C++內(nèi)存四區(qū)之代碼區(qū)、全局區(qū)、棧區(qū)和堆區(qū)

    C++編譯器會把代碼直接分為四個小區(qū),弄懂這四小區(qū)對我們理解內(nèi)存有所幫助,所以下面這篇文章主要給大家介紹了關(guān)于C++內(nèi)存四區(qū)之代碼區(qū)、全局區(qū)、棧區(qū)和堆區(qū)的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • C++賦值函數(shù)+移動賦值函數(shù)+移動構(gòu)造函數(shù)詳解

    C++賦值函數(shù)+移動賦值函數(shù)+移動構(gòu)造函數(shù)詳解

    這篇文章主要介紹了C++賦值函數(shù)+移動賦值函數(shù)+移動構(gòu)造函數(shù)詳解,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • C++實現(xiàn)控制臺版掃雷程序

    C++實現(xiàn)控制臺版掃雷程序

    這篇文章主要為大家詳細介紹了C++實現(xiàn)控制臺版掃雷程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言中volatile關(guān)鍵字的深入講解

    C語言中volatile關(guān)鍵字的深入講解

    在程序設(shè)計中,尤其是在C語言、C++、C#和Java語言中,使用volatile關(guān)鍵字聲明的變量或?qū)ο笸ǔ>哂信c優(yōu)化、多線程相關(guān)的特殊屬性,這篇文章主要給大家介紹了關(guān)于C語言volatile關(guān)鍵字的相關(guān)資料,需要的朋友可以參考下
    2021-07-07

最新評論

夹江县| 堆龙德庆县| 建始县| 炎陵县| 马关县| 云安县| 乌拉特前旗| 隆昌县| 克东县| 翁牛特旗| 福泉市| 仪征市| 泊头市| 贵定县| 哈巴河县| 集安市| 万州区| 望谟县| 富平县| 桐乡市| 泌阳县| 丹东市| 锡林浩特市| 贵德县| 崇州市| 雷波县| 无为县| 宜兰市| 石家庄市| 南昌县| 庆阳市| 襄城县| 米林县| 青河县| 新竹县| 林甸县| 泰安市| 揭西县| 黄大仙区| 崇阳县| 双柏县|