c++內存管理_復習

  • new與placement new
    • new:

      • 先調用operator new(大小),而operator new()會調用malloc嘗試分配內存,失敗則調用_callnewh()來釋放內存,直至分配成功
        • 可以設置分配失敗的處理函數:將寫好的處理函數作為參數傳入set_new_handler即可
      • 然后將得到的指針轉型
      • 最后通過指針調用構造函數
    • placement new
      placementnew

      • 先調用operator new(大小, address),該帶2個參數的函數直接返回buf,不做任何改動,即不分配內存。
      • 然后將得到的指針轉型
      • 最后通過指針調用構造函數

總結:new會分配內存后調用構造函數,而placement new相當于只是調用構造函數。因此我們可以像下面這樣模擬new的行為:
模擬new和delete

  • 容器的內存分配方式
    當元素放入容器時,容器也需要為其分配一塊空間,但其不是用的new和delete,而是將其包裝在construct()和destroy()函數中

  • 設計一個內存池

    • 重載局部的operator new()
      • 方法1:單獨多使用一些指針來將空閑塊連成鏈表
        下面在節點中使用next指針來將小塊鏈接起來

        void* A::operator new(size_t size)
        {cout << "局部new" << endl;A* p;if (!A::freeStore){//申請一大塊空間//A::freeStore = (A*)malloc(size * Chunk);A::freeStore = reinterpret_cast<A*>(new char[Chunk*size]);p = A::freeStore;//初始化p指針也指向頭節點//串成鏈表for (int i = 0; i < Chunk; i++){p->next = p + 1;//地址增大4,就是一個A的大小p = p->next;}p->next = NULL;}//把鏈表頭部的空閑塊拿出來用p = A::freeStore;A::freeStore = A::freeStore->next;return p;
        }
        
      • 使用嵌入式指針:也就是指針臨時借用一下空閑塊里的空間,等到需要分配出去使用時就正常使用即可。
        下面的rep和next占用同一片空間

        class A
        {
        private://數據struct Airplane//占8字節{int miles;char type;};
        private:union{Airplane rep;A* next;};static A* freeStore;//指向鏈表的頭部的指針static const int Chunk = 3;//內存池容納幾個
        public:static void* operator new(size_t size);static void operator delete(void* ptr);void set(int m, char t)....void show()....
        };
        
    • 重載局部的operator delete()
      • 采用頭插法,將空閑塊插入到鏈表頭
        void A::operator delete(void* ptr)
        {cout << "局部delete" << endl;//頭插法static_cast<A*>(ptr)->next = A::freeStore;A::freeStore = static_cast<A*>(ptr);
        }
        
    • c語言版本的內存池
      • 先寫個宏定義
        #define malloc(mp, size) _malloc(mp, size)
        #define free(mp, ptr) _free(mp, ptr)
        
      • 定義一個大的內存塊,這里稱其為頁
        typedef struct mempool_s
        {int block_size;//一小塊的大小int free_count;//該頁內剩余空閑塊的個數void *mem;//指向該頁首地址void *ptr;//指向該頁中最新創建的塊的地址(即下次要分配出去內存的塊)
        } mempool_t;
        
      • 寫一個內存池初始化函數,將128個小塊串成鏈表
        int memp_init(mempool_t *mp, size_t block_size)
        {printf("block_size: %ld\n", block_size);if (!mp) return -1;memset(mp, 0, sizeof(mempool_t));mp->block_size = block_size;mp->free_count = MEM_PAGE_SIZE / block_size;mp->mem = malloc(MEM_PAGE_SIZE);if(!mp->mem) return -1;mp->ptr = mp->mem;//把該頁中的128塊串成鏈表char *ptr = mp->ptr;//ptr指針指向第1塊for (int i = 0; i < mp->free_count; i++){//使用2級指針:一級指針ptr,(char**)ptr將其強轉為指向char*的指針,//*(char**)ptr為其指向的char*地址,將該地址賦值為ptr所指塊的下一塊地址*(char**)ptr = ptr + block_size;ptr += block_size;}*(char**)ptr = NULL;//最后一塊的前幾個字節保存的是NULLreturn 0;
        }
        
    • 最后寫內存分配與釋放的函數即可。釋放時同樣使用頭插法

- G2.9 alloc的大致流程:page8

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/35193.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/35193.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/35193.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue3 使用 Vue Router 時,params 傳參失效

前言&#xff1a; 在寫項目的時候&#xff0c;使用了 vue-router 的 params 進行傳參&#xff0c;但是在詳情頁面中一直獲取不到參數。原因&#xff1a;Vue Router 在2022-8-22的那次更新后&#xff0c;使用這種方式在新頁面上無法獲取&#xff01; 正文&#xff1a; 在列表頁進…

deeplabcut

import pandas as pd import h5py import pickle import json import os # 讀取 CSV 文件 csv_file_path /mnt/data/CollectedData_dlc.csv csv_data pd.read_csv(csv_file_path) # 讀取 H5 文件 h5_file_path /mnt/data/CollectedData_dlc.h5 with h5py.File(h5_file_pat…

LeetCode題練習與總結:只出現一次的數字Ⅱ--137

一、題目描述 給你一個整數數組 nums &#xff0c;除某個元素僅出現 一次 外&#xff0c;其余每個元素都恰出現 三次 。請你找出并返回那個只出現了一次的元素。 你必須設計并實現線性時間復雜度的算法且使用常數級空間來解決此問題。 示例 1&#xff1a; 輸入&#xff1a;n…

K8S日常運維手冊

Kubernetes&#xff08;簡稱 K8S&#xff09;是一種廣泛使用的容器編排平臺&#xff0c;能夠自動化部署、擴展和管理容器化應用。對于運維人員來說&#xff0c;掌握 Kubernetes 的日常運維技能是確保系統穩定運行的關鍵。本文將介紹一些 Kubernetes 日常運維的基本操作與技巧&a…

虛擬機裝入kali linux

VMware 首先需要先安裝VMware Workstation Pro可以根據這篇文章來下載VMware 下載kali linux Installer Images VS Virtual Machines Installer Images&#xff08;安裝鏡像&#xff09;Virtual Machines&#xff08;虛擬機&#xff09; 直接訪問硬件&#xff0c;定制內核…

Matlab|【防騙帖】考慮時空相關性的風電功率預測誤差建模與分析

目錄 1 主要內容 2 部分程序 3 下載鏈接 1 主要內容 這個程序《考慮時空相關性的風電功率預測誤差建模與分析》畫的圖片非常漂亮&#xff0c;和原文獻基本一致&#xff0c;但是實際上內容并未實現出來&#xff0c;主要就是利用現有的風電預測的數據和結果做了相關的圖&#…

【數據結構】(C語言):鏈表

鏈表&#xff1a; 基本單位是節點。節點至少兩部分&#xff1a;數據&#xff0c;下一個數據的地址。頭指針head&#xff0c;始終指向鏈表的第一個節點。若沒有節點&#xff0c;則headNULL。鏈表在內存中是非連續的。不能使用索引&#xff08;下標&#xff09;查找元素。只能從…

解決:Xshell通過SSH協議連接Ubuntu服務器報“服務器發送了一個意外的數據包,received:3,expected:20”

下圖所示&#xff1a; 日志也基本看不出來問題在哪&#xff0c;只是說斷開了連接大概是驗證失敗。有幸在某論壇評論區找到了原因&#xff0c;是因為我的xshell版本太低了而服務器的ssh版本太高&#xff0c;高版本的ssh默認屏蔽了一部分不太安全的算法導致建立連接的時候驗證失敗…

C++ 14新特性個人總結

variable templates 變量模板。這個特性允許模板被用于定義變量&#xff0c;就像之前模板可以用于定義函數或類型一樣。變量模板為模板編程帶來了新的靈活性&#xff0c;特別是在定義泛化的常量和元編程時非常有用。 變量模板的基本語法 變量模板的聲明遵循以下基本語法&am…

解決Vue+Vite打包后Leaflet的marker圖標不顯示的問題

前言 用Leaflet寫關于WebGIS的開發&#xff0c;用Vite或者webpack打包&#xff0c;打包后會找不到圖標&#xff0c;如下所示。 直言的說&#xff0c;筆者去網上搜了搜&#xff0c;其實收到一個比較好是答案。網址如下。 &#xff08;完美解決~&#xff09;關于VueLeaflet添加…

eslint 與 prettier 的一些常見的配置項(很詳細)

目錄 1、eslint 常見配置項&#xff08;語法規范&#xff09; 2、 prettier 常見的配置項&#xff08;格式規范&#xff09; 代碼規范相關內容看小編的該文章&#xff0c;獲取對你有更好的幫助 vsCode代碼格式化&#xff08;理解eslint、vetur、prettier&#xff0c;實現格式…

IDEA啟動報錯:Abnormal build process termination...

一、問題描述 因為項目需要&#xff0c;同時打開了兩個idea&#xff0c;突然發現一個啟動的時候報錯&#xff0c;有點莫名其妙&#xff0c;剛還好好的&#xff0c;為啥就不能用了&#xff0c;一頓百度找方法&#xff0c;試了各種方法&#xff0c;像重新安裝jdk、重啟系統發現都…

TensorFlow開源項目

歡迎來到 Papicatch的博客 文章目錄 &#x1f349;TensorFlow介紹 &#x1f349;主要特點和功能 &#x1f348;多語言支持 &#x1f348;靈活的架構 &#x1f348;分布式訓練 &#x1f348;跨平臺部署 &#x1f348;強大的工具鏈 &#x1f348;豐富的社區和生態系統 &a…

c++基本數據類型和計算(一)習題講解

1.【單選題】以下說法正確的是? A. unsigned 類型的值 最大為0xFFFFFFFF B. float類型的值大約有15位精度 C.bool類型占用4個字節 解析&#xff1a; 選項A&#xff1a;unsigned 類型的值 最大為 4個字節&#xff0c;正確。選項B&#xff1a; 因為float類型的值是單精度的浮…

Vue3基礎使用

目錄 一、創建Vue3工程 (一)、cli (二)、vite 二、常用Composition API (一)、setup函數 (二)、ref函數 (三)、reactive函數 (四)、setup注意事項 (五)、計算屬性 (六)、watch (七)、watchEffect函數 (八)、生命周期 1、以配置項的形式使用生命周期鉤子 2、組合式…

kafka-簡單代碼實現生產者消費者

生產者代碼&#xff1a; package com.kafka.test;import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.common.seriali…

【機器學習-10】 | Scikit-Learn工具包進階指南:Scikit-Learn工具包之支持向量機模塊研究

&#x1f3a9; 歡迎來到技術探索的奇幻世界&#x1f468;?&#x1f4bb; &#x1f4dc; 個人主頁&#xff1a;一倫明悅-CSDN博客 ?&#x1f3fb; 作者簡介&#xff1a; C軟件開發、Python機器學習愛好者 &#x1f5e3;? 互動與支持&#xff1a;&#x1f4ac;評論 &…

高考填報志愿攻略,5個步驟選專業和院校

在高考完畢出成績的時候&#xff0c;很多人會陷入迷茫中&#xff0c;好像努力了這么多年&#xff0c;卻不知道怎么規劃好未來。怎么填報志愿合適&#xff1f;在填報志愿方面有幾個內容需要弄清楚&#xff0c;按部就班就能找到方向&#xff0c;一起來了解一下正確的步驟吧。 第…

入局AI手機 蘋果公布Apple Intelligence

日前&#xff0c;蘋果WWDC 2024如期召開。在這持續1個小時44分鐘的開發者大會上&#xff0c;蘋果在前一個小時里更新了iOS、iPadOS、MacOS等操作系統&#xff0c;而且還首次更新了visionOS。余下的時間全部留給了蘋果的“AI大禮包”——Apple Intelligence&#xff08;蘋果智能…

請說明Thread類中run和start的區別,從方法的區別,及運行結果的區別分別說明

方法本身的區別 start() 方法&#xff1a; run()方法是Thread類的一個普通方法&#xff0c;它包含了線程要執行的代碼。當你直接調用一個線程的run()方法&#xff08;如myThread.run()&#xff09;&#xff0c;你實際上是在當前線程&#xff08;通常是主線程&#xff09;中執行…