C++學習日記 | LAB 6 static library 靜態庫

資料來源:南科大 余仕琪 C/C++ Program Design

LINK:CPP/week06 at main · ShiqiYu/CPP · GitHub


一、本節內容

? ? ? ? 本節主要介紹靜態庫和動態庫。

1.1 靜態庫和動態庫的概念

????????靜態鏈接和靜態庫(也稱為存檔)是鏈接器將所有使用的庫函數復制到可執行文件的結果。靜態鏈接會創建更大的二進制文件,并且需要更多的磁盤和主存空間。靜態庫的示例包括Linux中的.a文件和Windows中的.lib文件。

????????動態鏈接和動態庫動態鏈接不需要復制代碼,只需將庫的名稱放在二進制文件中即可。實際的鏈接發生在程序運行時,當二進制文件和庫都在內存中時。如果系統中的多個程序鏈接到同一動態鏈接庫,則它們都引用該庫。因此,該庫由多個程序共享,稱為“共享庫”。動態庫的示例包括Linux中的.so和Windows中的.dll。

1.2?靜態庫和動態庫的區別

?

優點缺點
靜態庫1.使可執行文件具有較少的依賴關系,已打包成可執行文件。
2.鏈接在編譯階段完成,代碼在執行過程中快速加載。
1.使可執行文件比那的更大。
2.作為依賴于另一個庫的庫將導致冗余副本,因為它必須與目標文件打包在一起。
3.升級不方便、不容易。需要替換并重新編譯整個可執行文件。
動態庫1.動態庫可以實現進程間的資源共享,只能有一個庫文件。
2.升級過程簡單,不需要重新編譯。
1.運行時加載會降低代碼的執行速度。
2.添加必須伴隨可執行文件的程序依賴項。

?1.3 靜態庫的建立方法

? ? ? ? ?假設我們編寫了以下代碼:

由于是靜態庫,已經生成了可執行文件,因此再次運行可執行文件時沒有庫文件也可以正常進行

二、習題筆記

習題1

存在的問題:使用new卻后續沒有釋放內存(gpt說的)

????????問題出在使用?new int[SIZE]?分配內存的那一行。當使用?new?動態分配內存時,需要在使用完后使用?delete?來釋放這塊內存。然而,在代碼中,沒有相應的?delete?語句來釋放為?pa?分配的內存。

????????為了解決這個問題,使用智能指針可以自動管理內存,避免手動釋放的問題。例如,std::unique_ptr<int> p(new int);?將在作用域結束時自動釋放內存。

#include <iostream>
#include <memory> // Include the <memory> header for std::unique_ptrusing namespace std;#define SIZE 5int sum(const int *pArray, int n)
{int s = 0;for (int i = 0; i < n; i++)s += pArray[i];return s;
}int main()
{// Use std::unique_ptr to manage memoryunique_ptr<int[]> pa(new int[SIZE]{3, 5, 8, 2, 6});int total = sum(pa.get(), SIZE); // Use pa.get() to access the raw pointercout << "sum = " << total << endl;// No need to manually delete pa; it will be automatically cleaned up when it goes out of scopereturn 0;
}


  • ?什么情況下應該使用裸指針而不是智能指針?
  1. 裸指針(原生指針)

    • 裸指針是指直接使用?T*?類型的指針,沒有被智能指針封裝。
    • 適用情況:
      • 無所有權語義:當你不需要管理資源的所有權時,可以使用裸指針。例如,函數參數傳遞時,如果不涉及資源所有權的轉移,可以使用裸指針或引用。
      • 性能要求高:裸指針操作更輕量,不涉及引用計數等開銷,適用于性能敏感的場景。
  2. 智能指針

    • 智能指針是 C++ 提供的 RAII(資源獲取即初始化)機制的一部分,用于管理動態分配的內存。
    • 適用情況:
      • 資源管理:在資源獲取時,應優先使用智能指針。它們可以自動清理內存,避免內存泄漏。
      • 明確所有權:當需要明確資源的所有權轉移時,使用?std::unique_ptr?或?std::shared_ptr
      • 線程安全std::shared_ptr?可以在多線程環境中共享資源。
  3. 總結

    • 使用裸指針時,要確保不會出現懸空指針、多次釋放等問題。
    • 使用智能指針時,可以更安全地管理資源,但要根據具體情況選擇合適的類型。

習題2

仿真結果:

?問題分析

????????在?create_array?函數中,聲明了一個名為?arr?的整數數組,并在函數內部對其進行賦值。然后,返回了指向這個局部數組的指針?arr。問題在于,局部數組?arr?是在棧上分配的,而指針?ptr?在?main?函數中持有這個指向局部數組的地址。當?create_array?函數結束時,局部數組?arr?將被銷毀,但指針?ptr?仍然指向已經不存在的內存區域

????????為了避免內存泄漏,我們需要使用動態分配的內存(在堆上分配)來存儲數組。我們可以使用?new?運算符來分配堆內存,并返回指向堆內存的指針。

#include <iostream>
using namespace std;int *create_array(int size)
{int *arr = new int[size]; // 使用 new 分配堆內存for (int i = 0; i < size; i++)arr[i] = i * 10;return arr;
}int main()
{int len = 16;int *ptr = create_array(len);for (int i = 0; i < len; i++)cout << ptr[i] << " ";delete[] ptr; // 釋放堆內存return 0;
}

仿真結果:

習題3

問題分析:sum函數中常數指針不能被修改賦值

修改方案:將pa改為普通指針

#include <iostream>
#define SIZE 5
void sum( int *, const int *, int);int main() 
{int a[SIZE] = {10,20,30,40,50};int b[SIZE] = {1,2,3,4,5};std::cout << "Before calling the function, the contents of a are:" << std::endl;for(int i = 0; i < SIZE; i++)std::cout << a[i] << " ";// passing arrays to functionsum(a,b,SIZE);std::cout << "\nAfter calling the function, the contents of a are:" << std::endl;for(int i = 0; i < SIZE; i++)std::cout << a[i] << " ";std::cout << std::endl;return 0;
}void sum( int *pa, const int *pb, int n)
{for(int i = 0; i < n; i++){*pa += *pb;pa++;pb++;}
}

?

習題4

swap.hpp

#ifndef __SWAP_HPP__
#define __SWAP_HPP__
void swap(int& a, int& b);
#endif

swap.cpp

#include <iostream>
#include "swap.hpp"void swap(int& a, int& b)
{int temp = a;a = b;b = temp;
}

main.cpp

#include <iostream>
#include "swap.hpp"int main()
{int x = 10;int y = 20;std::cout << "Before swapping: x = " << x << ", y = " << y << std::endl;// 調用交換函數swap(x, y);std::cout << "After swapping: x = " << x << ", y = " << y << std::endl;return 0;
}

????????按照1.3節內容進行操作,結果如下所示、將生成的libswap.a庫文件移除之后仍然可以正常運行可執行文件,表面成功建立靜態庫。

? ? ? ?在編寫swap.cpp中使用了引用(參考C++學習日記 | Lecture 6 函數-CSDN博客)而不是傳統的參數作為函數輸入。

使用引用作為函數的輸入

  1. 引用可以直接修改原始變量的值:?當我們傳遞參數時,如果使用引用,我們實際上傳遞的是原始變量的引用,而不是它的副本。這意味著在函數內部對引用的修改會直接影響原始變量。如果我們使用值傳遞(int),則函數內部的修改只會影響參數的副本,而不會影響原始變量。

  2. 效率更高:?使用引用避免了復制大型對象的開銷。當我們傳遞大型結構體或類對象時,使用引用可以提高性能,因為不需要復制整個對象。

  3. 語義更清晰:?使用引用可以更清楚地表達我們的意圖。當我們在函數中看到引用參數時,我們知道這個函數可能會修改原始變量的值。

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

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

相關文章

Javascript中的定時器有哪些?他們的區別及用法是什么?

JavaScript 中有幾種常用的定時器函數,它們的區別主要在于執行方式和行為: setTimeout(callback, delay):作用:在指定的延遲時間后執行回調函數一次。用法:通常用于延遲執行某些操作。返回值:一個定時器 ID,可用于取消定時器。setInterval(callback, delay):作用:每隔指定的延…

Linux中 “權限設置修改”

目錄 一、權限 &#xff08;1&#xff09;權限三大類&#xff1a; &#xff08;2&#xff09;文件的權限&#xff1a; &#xff08;3&#xff09;目錄的權限&#xff1a; &#xff08;4&#xff09;用戶的角色&#xff1a; 二、文件的權限位 三、修改用戶權限 &#xf…

【flutter 雙端開發】

flutter 雙端開發 開發小細節替換新的logo 開發小細節 替換新的logo 替換雙端logo 尋找三方插件 android 打包流程 android 打包流程2

小程序唯品會Authorization sign

聲明 本文章中所有內容僅供學習交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包內容、敏感網址、數據接口等均已做脫敏處理&#xff0c;嚴禁用于商業用途和非法用途&#xff0c;否則由此產生的一切后果均與作者無關&#xff01;wx a15018601872 本文章未…

Python---Matplotlib(2萬字總結)【從入門到掌握】

數據可視化 在完成了對數據的透視之后&#xff0c;可以將數據透視的結果通過可視化的方式呈現出來&#xff0c;簡單的說&#xff0c;就是將數據變成漂亮的圖表&#xff0c;因為人類對顏色和形狀會更加敏感&#xff0c;然后再進一步解讀數據背后隱藏的價值。在之前的文章中已經…

nacos安裝與使用

1.nacos簡介與安裝 什么是注冊中心&#xff08;服務治理&#xff09; 服務注冊&#xff1a;服務提供者provider&#xff0c;啟動的時候向注冊中心上報自己的網絡信息 服務發現&#xff1a;服務消費者consumer&#xff0c;啟動的時候向注冊中心上報自己的網絡信息&#xff0c;拉…

JavaScript style 樣式屬性操作

JavaScript 中可以使用 style 對象來操作元素的樣式屬性。style 對象是元素的一個屬性&#xff0c;通過它可以訪問和修改元素的內聯樣式屬性。 要訪問元素的樣式屬性&#xff0c;可以使用以下語法&#xff1a; element.style.property 其中&#xff0c;element 是要操作的元…

centos7防火墻入站白名單配置

firewall-cmd --set-default-zonedropfirewall-cmd --get-active-zone記錄下當前激活網卡firewall-cmd --permanent --change-interfaceens33 --zonedrop firewall-cmd --zonedrop --list-all 添加信任的源IP和開放端口 firewall-cmd --permanent --add-source192.168.254.1 -…

【OpenCV】圖形繪制與填充

介紹了繪制、填充圖像的API。也介紹了RNG類用來生成隨機數。相關API&#xff1a; line() rectangle() circle() ellipse() putText() 代碼&#xff1a; #include "iostream" #include "opencv2/opencv.hpp"using namespace std; using namespace cv…

ARM64的KASLR分析

基本概念 加載地址&#xff1a;內核解壓到物理內存上的物理起始地址 鏈接地址&#xff1a;內核編譯鏈接后的虛擬起始地址 我們的這篇 文章&#xff0c;介紹了加載地址可以是自動的&#xff0c;也可以是固定的&#xff1b;一般都是物理內存的起始地址 一個偏移 &#xff1b;…

pillow學習3

Pillow庫中&#xff0c;圖像的模式代表了圖像的顏色空間。以下是一些常見的圖像模式及其含義&#xff1a; L&#xff08;灰度圖&#xff09;&#xff1a;L模式表示圖像是灰度圖像&#xff0c;每個像素用8位表示&#xff08;范圍為0-255&#xff09;&#xff0c;0表示黑色&#…

在flutter initState 方法,觸發 setState導致循環執行

在Flutter中&#xff0c;如果你在initState中調用了一個方法&#xff0c;并且這個方法可能導致狀態更新&#xff0c;這可能會引起無限循環&#xff0c;因為每次狀態更新都會再次調用initState。 為了避免這種情況&#xff0c;你應該檢查調用的方法是否會導致狀態更新&#xff…

圖算法新書發布會圓滿成功,大咖現場都講了啥?

5月24日&#xff0c;嬴圖與機工社攜手舉辦的“《圖算法&#xff1a;行業應用與實踐》新書發布會”圓滿成功。 現場直播在線觀眾達4000人/次左右&#xff0c;點贊數量超7000&#xff0c;直至發布會尾聲&#xff0c;觀看人數仍在持續增長。 通過觀眾們的反饋&#xff0c;我們也對…

Matplotlib 實踐指南:圖形樣式、風格與標記探索

目錄 前言 第一點&#xff1a;導入模塊 第二點&#xff1a;創建二維圖 第三點&#xff1a;創建統計圖 總結 前言 Matplotlib 是一個強大的數據可視化庫&#xff0c;可用于創建各種類型的圖形。在本文中&#xff0c;我們將研究如何在 Matplotlib 中設置圖形的顏色、風格和標記…

【LeetCode算法】第88題:合并兩個有序數組

目錄 一、題目描述 二、初次解答 三、官方解法 四、總結 一、題目描述 二、初次解答 1. 思路&#xff1a;首次想到的解法&#xff1a;定義一個mn長度的輔助數組&#xff0c;從頭遍歷這兩個數組&#xff0c;誰小就放進輔助數組中并且對應往后走&#xff0c;最后使用memcpy函…

巧用java8的stream流的.collect(Collectors.toMap(arg1,arg2))

最近公司接手了一個低代碼二次開發平臺的需求&#xff0c;需要連接多張表的數據然后展示到界面上。 按照java的sql思路&#xff0c;我們直接通過left join去關聯表就行了&#xff0c;但是該低代碼平臺有對sql連表查詢有限制&#xff0c;就是有些表它是存在一個domainKey的&…

HotSpot虛擬機的幾個實現細節

文章目錄 STW安全點安全區域記憶集與卡表讀寫屏障 STW 收集器在根節點枚舉這步都是必須要暫停用戶線程的&#xff08; STW &#xff09;&#xff0c;如果不這樣的話在根節點枚舉的過程中由于引用關系在不斷變化&#xff0c;分析的結果就不準確 安全點 收集器在工作的時候某些…

切勿安裝這五款流氓軟件,你中招了沒

流氓軟件&#xff0c;又稱為惡意軟件&#xff0c;是一類設計用來損害用戶設備、竊取信息或干擾正常使用的程序。以下是五款臭名昭著的流氓軟件介紹&#xff0c;提醒切勿安裝&#xff0c;只能說一個比一個毒&#xff0c;你中招了沒 可以去去虛擬機試試誰的毒更強一些&#xff0…

高工咨詢:《2024中國人形機器人產業發展藍皮書》

高工咨詢所發布的《2024中國人形機器人產業發展藍皮書》全面梳理了人形機器人產業的發展現狀、政策環境、資本市場、技術發展、市場前景以及面臨的機遇與挑戰等情況。 人形機器人是當今世界科技領域最具潛力和前景的產業之一。隨著科技的不斷進步和人 工智能技術的快速發展&…

基于jeecgboot-vue3的Flowable增加表單功能(二)

因為這個項目license問題無法開源&#xff0c;更多技術支持與服務請加入我的知識星球。 接上一節 6、增加一個types.ts 類型 export interface FormForm {id: number | string | undefined;formName: string;formContent?: string;remark: string; } 7、api增加一個getForm…