侯捷 C++ 課程學習筆記:內存管理與工具應用

一、課程基礎要求

首先強調了學習前應具備的基礎知識。這些基礎知識對于理解 C++ 的核心概念和編程技巧至關重要。

  • 動態內存分配與使用

    • 理解動態內存分配的概念,掌握 newdelete 操作符的使用。

    • 能夠動態分配和管理內存,避免內存泄漏和非法訪問。

  • C++ 標準庫的容器

    • 熟悉 C++ 標準庫中的容器,如 vectorlistmap 等。

    • 掌握容器的使用方法,包括插入、刪除、遍歷等操作。

動態內存分配,這個概念在C++里挺重要的。我記得以前在學校學過,但可能有些細節需要再復習一下。首先,動態內存分配是什么意思呢?應該是在程序運行時根據需要分配內存,而不是在編譯時固定大小。比如,當我們需要一個數組,但不確定它會有多大時,用動態分配就可以在運行時決定大小。對吧?

那C++里用new和delete操作符來管理動態內存。new用來分配內存,delete用來釋放。比如,想要一個int,可以int* p = new int; 然后賦值*p = 5; 使用完后要delete p; 對吧?這樣就不會內存泄漏了。但是如果忘記delete的話,就會導致內存泄漏,這確實是個問題。

那動態數組呢?比如int* arr = new int[10]; 這樣分配一個10個int的數組,釋放的時候要用delete[] arr;。這里容易出錯的地方可能就是用了delete而不是delete[],這樣可能導致未定義行為,比如只釋放了第一個元素,剩下的沒釋放,或者破壞堆的結構?

還有內存泄漏的情況,比如在函數里分配了內存,但沒有在返回前釋放,或者因為異常導致delete沒有被執行。這時候需要用智能指針比如unique_ptr或shared_ptr來管理,自動釋放內存。不過我們主要了解new和delete,所以暫時不考慮智能指針的話,需要注意手動管理。

另外,非法訪問的問題,比如分配了n個元素,但訪問第n+1個元素,這會導致越界,可能引發崩潰或安全漏洞。動態分配的內存需要自己確保不越界訪問,不像vector有邊界檢查。

那怎么避免內存泄漏呢?確保每一個new都有對應的delete,并且在正確的時機調用。比如在函數中,如果有多個返回點,每個可能的路徑都要有delete。或者使用RAII(資源獲取即初始化)技術,把指針封裝在對象里,析構時自動釋放。

比如,寫一個類,構造函數中用new分配內存,析構函數中用delete釋放。這樣當對象離開作用域時,自動調用析構函數,釋放內存。這樣可以避免忘記delete的情況。

另外,使用new的時候可能會拋出std::bad_alloc異常,如果內存不足的話。這時候要考慮異常安全,確保在異常發生時已經分配的資源能被正確釋放。或者使用nothrow版本的new,比如int* p = new(nothrow) int; 這樣在分配失敗時返回nullptr,而不是拋出異常。

還有,淺拷貝的問題。如果一個類有動態分配的成員,默認的拷貝構造函數和賦值運算符會進行淺拷貝,導致多個指針指向同一塊內存。這樣在析構時可能會多次delete同一塊內存,導致未定義行為。這時候需要自己實現深拷貝,或者在C++11以后使用移動語義。

總結一下,動態內存管理需要注意以下幾點:

1. 正確配對使用new和delete,new[]和delete[]。

2. 避免內存泄漏,確保所有分配的內存都被釋放。

3. 防止懸空指針,釋放后不要繼續使用指針。

4. 避免越界訪問動態分配的數組。

5. 處理可能的異常情況,確保異常安全。

6. 使用RAII或智能指針來自動管理內存,減少手動管理的錯誤。

比如,舉個簡單的例子,動態分配一個整數:

int* ptr = new int;

*ptr = 10;

// 使用ptr

delete ptr;

如果忘記delete,ptr指向的內存就泄漏了。或者如果在delete之后再次使用ptr,就會訪問已經釋放的內存,導致未定義行為。

再比如動態數組:

int size = 5;

int* arr = new int[size];

for(int i=0; i<size; i++) {

arr[i] = i;

}

// 使用數組

delete[] arr;

這里如果錯誤地使用delete arr; 而不是delete[] arr;,會導致問題,因為前者只調用一次析構函數(如果有對象的話),而后者正確釋放整個數組的內存。

還有,當在函數中動態分配內存并返回指針時,調用者需要負責釋放,這容易出錯。比如:

int* createArray(int size) {

return new int[size];

}

void someFunction() {

int* myArr = createArray(10);

// ... 使用myArr

delete[] myArr; // 必須記得

}

如果調用者忘記delete[],就會泄漏。所以最好返回智能指針,或者讓調用者明確責任。

總的來說,正確使用new和delete需要嚴格的代碼紀律,確保每個分配都有對應的釋放,并且正確處理所有可能的執行路徑和異常情況。而使用現代C++的智能指針可以大大減少這些問題,但理解底層機制還是很重要的。

二、課程目標

????????課程的目標是幫助學員從基礎到高級,全面掌握 C++ 編程語言的各個方面。

  • 從基礎到高級

    • 從最基礎的 C++ 語言構件,如變量、類型、作用域、循環、流程控制等,逐步深入到高級主題,如內存管理、類和對象、模板編程等。

    • 通過系統的學習,幫助學員構建扎實的 C++ 編程基礎,為后續的高級開發打下堅實的基礎。

  • 內存管理器

    • 學習高知名度的內存管理器,如 STL Allocators、Boost.Pool、jemalloc 等。

    • 理解內存管理器的工作原理和應用場景,掌握如何在實際項目中選擇和使用合適的內存管理器。

三、工具與環境

課程中介紹了多種開發工具和環境,幫助學員更好地進行 C++ 編程實踐。

  • Dev-C++

    • Dev-C++ 是一個免費的 C++ 集成開發環境(IDE),支持 GNU 編譯器(GCC)。

    • 通過 Dev-C++,學員可以方便地編寫、編譯和調試 C++ 代碼,進行項目管理和代碼管理。

  • Visual C++ 6.0

    • Visual C++ 6.0 是微軟推出的一個經典的 C++ 開發環境,支持 MFC(Microsoft Foundation Classes)等框架。

    • 通過 Visual C++ 6.0,學員可以學習如何使用 MFC 進行 Windows 應用程序開發,掌握 MFC 的基本使用方法。

四、實際應用案例

在實際應用中,動態內存分配和標準庫容器的使用非常廣泛。

  • 動態內存分配

    • 示例代碼

      int* ptr = new int(10);  // 動態分配一個整數
      std::cout << *ptr << std::endl;  // 輸出 10
      delete ptr;  // 釋放動態分配的內存
  • 標準庫容器

    • 示例代碼

      std::vector<int> vec;  // 創建一個整數向量
      vec.push_back(1);  // 添加元素 1
      vec.push_back(2);  // 添加元素 2
      vec.push_back(3);  // 添加元素 3
      for (int i : vec) {std::cout << i << " ";  // 輸出 1 2 3
      }
五、學習資源

課程中還推薦了一些網絡資源和書籍,幫助學員進一步學習和深入理解 C++ 編程。

  • 網絡資源

    • Doug Lea 的主頁:Doug Lea 是 C++ 標準模板庫(STL)的主要作者之一,他的主頁上提供了許多關于 STL 和內存管理的資源。

    • CSDN:CSDN 是一個大型的中文技術社區,提供了豐富的 C++ 編程資源和教程。

  • 書籍

    • 《STL源碼剖析》:侯捷老師本人著,詳細解析了 STL 的源碼,幫助學員深入理解 STL 的實現原理。

    • 《Small Memory Software》:James Noble 和 Charles Weir 著,介紹了在有限內存系統中設計和實現小內存軟件的模式和方法。

    • 《Modern C++ Design》:Andrei Alexandrescu 著,介紹了現代 C++ 設計模式和泛型編程的應用。

六、學習心得

通過學習侯捷老師的 C++ 課程,我對 C++ 的內存管理和工具應用有了更深入的理解。課程內容從基礎到高級,逐步引導學員掌握 C++ 的核心概念和編程技巧。特別是對動態內存分配和標準庫容器的使用,為后續的面向對象編程和高級開發打下了堅實的基礎。

在實際編程中,合理使用動態內存分配和標準庫容器可以顯著提高代碼的可讀性和可維護性。同時,掌握開發工具和環境的使用,可以提高開發效率,更好地進行項目管理和代碼管理。

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

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

相關文章

python: SQLAlchemy (ORM) Simple example using SQLite

領域層&#xff08;Domain Laye&#xff09;&#xff1a;定義了 School 實體類和 SchoolRepository 抽象基類&#xff0c;明確了業務實體和數據訪問的契約。 基礎設施層&#xff08;Infrastructure Laye&#xff09;&#xff1a;通過 SQLAlchemy 實現了 SchoolRepository 類&am…

fastadmin實現海報批量生成、郵件批量發送

記錄一個海報批量生成、郵件批量發送功能開發&#xff0c;業務場景如下&#xff1a; 國外客戶做觀展預登記&#xff0c;工作人員通過后臺&#xff0c;批量給這些觀眾生成入場證件并發送到觀眾登記的郵箱&#xff0c;以方便觀眾入場時快速進場。證件信息包含入場二維碼、姓名&a…

solidity之Foundry安裝配置(一)

一門面向合約的高級編程語言&#xff0c;主要用來編寫以太坊只能合約。 Solidity受C語言&#xff0c;Python和js影響&#xff0c;但為編譯成為以太坊虛擬機字節碼在EVM上執行&#xff0c;很多特性和限制都和EVM相關。 Solidity 是靜態類型語言&#xff0c;支持繼承、庫、自定義…

功能全面的手機壁紙應用,種類齊全、眾多高清壁紙

軟件介紹 應用亮點&#xff1a;今天給大家分享一款超神奇的手機應用 —— 奇幻壁紙。它作為手機動態壁紙軟件&#xff0c;功能超全面&#xff0c;操作還便捷&#xff0c;極具創意&#xff0c;能瞬間將你的手機屏幕變成奇幻世界&#xff0c;帶來全新視覺感受。 使用便捷性&…

使用docker配置PostgreSQL

配置docker阿里云鏡像倉庫 國內使用docker hub拉取鏡像比較慢&#xff0c;所以首先配置個人的鏡像倉庫。 阿里云的個人鏡像倉庫是免費的&#xff0c;對個人來說足夠用。 具體操作參考阿里云官方鏈接 。 關于個人鏡像倉庫的使用參考鏈接。 配置完個人鏡像倉庫后將公網配置到doc…

基于Dancing Links的精確覆蓋算法(解決NP難問題)和量子計算機模擬中的Shor算法(涉及數論與量子疊加態模擬)

一、Dancing Links算法實現數獨求解(NP難問題) 算法方案 數獨可轉化為精確覆蓋問題,使用Knuth提出的DLX算法實現高效求解。該算法通過雙向十字循環鏈表實現快速回溯,時間復雜度可達O(n^k)(k為常數) #include <iostream> #include <vector> #include <c…

Spring Boot定時任務原理

Spring Boot定時任務原理 在現代應用中&#xff0c;定時任務的調度是實現周期性操作的關鍵機制。Spring Boot 提供了強大的定時任務支持&#xff0c;通過注解驅動的方式&#xff0c;開發者可以輕松地為方法添加定時任務功能。本文將深入探討 Spring Boot 中定時任務的實現原理…

【跟我學YOLO】(1)YOLO12:以注意力為中心的物體檢測

歡迎關注『跟我學 YOLO』系列 【跟我學YOLO】&#xff08;1&#xff09;YOLO12&#xff1a;以注意力為中心的物體檢測] 0. YOLOv12 簡介0.1 YOLO12 論文下載0.2 YOLO12 的主要改進0.3 YOLO12 支持的任務和性能0.4 論文摘要 1. 背景介紹2. 相關的工作3. 方法3.1 效率分析3.2 區域…

LTO優化詳解

嵌入式開發過程中的LTO優化是什么意思&#xff1f;能夠用來解決什么問題&#xff1f;它都優化了哪些&#xff1f;僅開啟LTO真的可以優化SIZE的問題嗎? 請分別回答我剛才提到的問題&#xff1f; 嗯&#xff0c;用戶問關于嵌入式開發中的LTO優化&#xff0c;我需要詳細解釋這個概…

leetcode_位運算 231.2的冪

231. 2的冪 給你一個整數n&#xff0c;請你判斷該整數是否是 2 的冪次方。如果是&#xff0c;返回 true &#xff1b;否則&#xff0c;返回 false。 如果存在一個整數 x 使得 n 2x &#xff0c;則認為 n 是 2 的冪次方 思路: 2的冪運算的結果中&#xff0c;其二進制數里只有…

VSCode - VSCode 切換自動換行

VSCode 自動換行 1、基本介紹 在 VSCode 中&#xff0c;啟用自動換行可以讓長行代碼自動折行顯示&#xff0c;避免水平滾動條頻繁使用&#xff0c;提升代碼閱讀體驗 如果禁用自動換行&#xff0c;長行代碼就需要手動結合水平滾動條來閱讀 2、演示 啟用自動換行 禁用自動換…

CSS `transform` 屬性詳解:打造視覺效果與動畫的利器

CSS transform 屬性詳解&#xff1a;打造視覺效果與動畫的利器 引言一、transform 屬性簡介二、平移&#xff08;Translation&#xff09;三、旋轉&#xff08;Rotation&#xff09;四、縮放&#xff08;Scale&#xff09;五、傾斜&#xff08;Skew&#xff09;六、組合變換&am…

算法每日一練 (5)

&#x1f4a2;歡迎來到張胤塵的技術站 &#x1f4a5;技術如江河&#xff0c;匯聚眾志成。代碼似星辰&#xff0c;照亮行征程。開源精神長&#xff0c;傳承永不忘。攜手共前行&#xff0c;未來更輝煌&#x1f4a5; 文章目錄 算法每日一練 (5)旋轉鏈表題目描述解題思路解題代碼c/…

51單片機-按鍵

1、獨立按鍵 1.1、按鍵介紹 輕觸開關是一種電子開關&#xff0c;使用時&#xff0c;輕輕按開關按鈕就可使開關接通&#xff0c;當松開手時&#xff0c;開關斷開。 1.2、獨立按鍵原理 按鍵在閉合和斷開時&#xff0c;觸點會存在抖動現象。P2\P3\P1都是準雙向IO口&#xff0c;…

BFS 和 DFS(深度優先搜索、廣度優先搜索)

深度優先搜索&#xff08;DFS&#xff09;和廣度優先搜索&#xff08;BFS&#xff09;是兩種常用的圖遍歷算法&#xff0c;用于解決圖相關的問題。它們在搜索問題中具有廣泛的應用&#xff0c;如路徑搜索、連通性檢測等。 以下是具體區別&#xff1a; &#xff08;圖片引自&am…

推薦幾款較好的開源成熟框架

一. 若依&#xff1a; 1. 官方網站&#xff1a;https://doc.ruoyi.vip/ruoyi/ 2. 若依SpringBootVueElement 的后臺管理系統&#xff1a;https://gitee.com/y_project/RuoYi-Vue 3. 若依SpringBootVueElement 的后臺管理系統&#xff1a;https://gitee.com/y_project/RuoYi-Cl…

根據音頻中的不同講述人聲音進行分離音頻 | 基于ai的說話人聲音分離項目

0.研究背景 在實際的開發中可能會遇到這樣的問題&#xff0c;老板讓你把音頻中的每個講話人的聲音分離成不同的音頻片段。你可以使用au等專業的音頻處理軟件手動分離。但是這樣效率太慢了&#xff0c;現在ai這么發達&#xff0c;我們能否借助ai之力來分離一條音頻中的不同的說…

本地化部署 DeepSeek:從零到一的完整指南

本地化部署 DeepSeek&#xff1a;從零到一的完整指南 個人主頁&#xff1a;顧漂亮 文章專欄&#xff1a;AI學習 目錄 引言什么是 DeepSeek&#xff1f;為什么選擇本地化部署&#xff1f;DeepSeek 本地化部署的前期準備 硬件需求軟件需求環境配置 DeepSeek 本地化部署步驟 步驟…

使用ArcGIS Pro自動矢量化水系

在地理信息系統&#xff08;GIS&#xff09;領域&#xff0c;自動矢量化是一項至關重要的技術&#xff0c;它能夠將柵格圖像中的要素轉換為矢量數據&#xff0c;從而方便后續的分析和處理。本文將詳細介紹如何使用ArcGIS Pro自動矢量化水系&#xff0c;適用于那些顏色相對統一、…

C++類和對象進階:初始化列表和static成員深度詳解

C類和對象&#xff1a;初始化列表和static成員深度詳解 1. 前言2. 構造函數初始化成員變量的方式2.1 構造函數體內賦值2.2 初始化列表2.2.1 初始化列表的注意事項 2.3 初始化列表的初始化順序 3. 類的靜態成員3.1 引入3.2 靜態成員變量3.3 靜態成員函數3.4 靜態成員的注意事項3…