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_ptr

using namespace std;

#define SIZE 5

int 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 memory
    unique_ptr<int[]> pa(new int[SIZE]{3, 5, 8, 2, 6});

    int total = sum(pa.get(), SIZE); // Use pa.get() to access the raw pointer
    cout << "sum = " << total << endl;

    // No need to manually delete pa; it will be automatically cleaned up when it goes out of scope

    return 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 function
    sum(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. 语义更清晰: 使用引用可以更清楚地表达我们的意图。当我们在函数中看到引用参数时,我们知道这个函数可能会修改原始变量的值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/654269.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

存内计算从浮点运算优化对数据经济的提升

本篇文章将介绍存内计算技术对于数据经济的提升&#xff0c;我们将从提出问题、解答问题与阐述应用三个方面进行展开介绍&#xff0c;并引入浮点存算、等新兴存算技术进行简要介绍。 一.数据经济&存内计算&#xff0c;结合是否可行&#xff1f; 数据经济与存内计算&#…

恭喜社区迎来新PMC成员!

恭喜Apache SeaTunnel社区又迎来一位PMC Memberliugddx&#xff01;在社区持续活跃的两年间&#xff0c;大家经常看到这位开源爱好者出现在社区的各种活动中&#xff0c;为项目和社区发展添砖加瓦。如今成为项目PMC Member&#xff0c;意味着在社区中的责任更重了&#xff0c;他…

Github Page 部署失败

添加 .gitmodules 文件 [submodule "themes/ayer"]path themes/ayerurl https://github.com/Shen-Yu/hexo-theme-ayer.git 添加 .nojekyll 文件

文心一言 VS 讯飞星火 VS chatgpt (269)-- 算法导论20.2 4题

四、修改 proto-vEB 结构&#xff0c;以支持重复关键字。如果要写代码&#xff0c;请用go语言。 文心一言&#xff1a; 在原始的 van Emde Boas 树&#xff08;vEB tree&#xff09;结构中&#xff0c;关键字&#xff08;key&#xff09;是唯一的&#xff0c;不允许有重复的关…

.NET 轻量级、高效任务调度器:ScheduleTask

前言 至于任务调度这个基础功能&#xff0c;重要性不言而喻&#xff0c;大多数业务系统都会用到,世面上有很多成熟的三方库比如Quartz&#xff0c;Hangfire&#xff0c;Coravel 这里我们不讨论三方的库如何使用 而是从0开始自己制作一个简易的任务调度,如果只是到分钟级别的粒…

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 -…

pikachu—exec“eval“

这是原画面 然后呢&#xff1f; 我们知道会传入到后台rce_eval.php来处理然后通过 eval()是啥? 在eval括号里面可以执行外来机器的命令 然后我们通过php的一个内置的命令 我们通过phpinfo()&#xff1b; 这是输入后的结果

华为机考入门python3--(26)牛客26-字符串排序

分类&#xff1a;字符串 知识点&#xff1a; 字符串是否仅由字母构成 my_str.isalpha() 字母列表按小写排序 letters.sort(keylambda x: x.lower()) 题目来自【牛客】 def custom_sort(input_str):letters []non_letters []for char in input_str:if char.isalpha…

打工人都在偷偷做的副业项目—steam搬砖

steam搬砖其实是一个非常老牌的项目了&#xff0c;之前只有玩游戏玩市场的人知道&#xff0c;其他普通人都不知道。 我们陪跑这个项目不是说这个项目不行了&#xff0c;再拿出来割韭菜&#xff0c;现在依然可以做&#xff0c;我们本身就是项目和培训一比一在做&#xff0c;这一…

R语言学习 - 箱线图一步法

箱线图 - 一步绘制 绘图时通常会碰到两个头疼的问题&#xff1a; 1、有时需要绘制很多的图&#xff0c;唯一的不同就是输入文件&#xff0c;其它都不需要修改。如果用R脚本&#xff0c;需要反复替换文件名&#xff0c;繁琐又容易出错。 (R也有命令行参数&#xff0c;不熟&…

关于高性能滤波器和普通型滤波器的区别说明

高性能滤波器和普通型滤波器在性能和滤波效果上存在显著差异。以三安培为代表分析高性能滤波器和普通型滤波器的区别&#xff1a; 从上图曲线可看出&#xff1a; 1.高性能滤波器和普通型滤波器的滤波范围不同。普通型滤波器有效滤波范围为 150KHz~30MHz&#xff0c;而高性能滤…

QColor官网文档简介

颜色可以用不同的模型来进行表示,常见的有RGB,HSV或者CMYK.QColor基于RGB值创建颜色,如果要转接到HSV或者CMYK需要使用转接函数toHsv() toCmyk() 返回期望格式的副本 get...和set...函数具体参见文档用isValid()检查RGB颜色是否合法颜色组成部分可以单独检索QRgb是一种无符号整…

Hololens 2 新建自定义按钮

官方链接地址 1、创建Cube 2、添加PressableButton脚本&#xff0c;并点击AddNearin… 3、把Cube拖入到MovingButtonVisuals变量中 4、点击NearInteractionTouchable组件&#xff08;这个组件是添加和上一个脚本绑定的&#xff0c;自动添加上来的&#xff09;上的Fix… 5、…

一文搞懂oracle事务提交以及脏数据落盘的原则

本文基于oracle 19c 做事务提交以及oracle脏数据落盘的相关解读 第一章 相关进程及组件介绍&#xff1a; 1.LGWR&#xff1a; 重做日志条目在系统全局区域 &#xff08;SGA&#xff09; 的重做日志缓冲区中生成。LGWR 按顺序将重做日志条目写入重做日志文件。如果数据库具有…

14.Redis之JAVASpring客户端

1.引入依赖 此时就会引入操作 redis 的依赖了~~ 2.yml配置 spring:redis:host: 127.0.0.1port: 8888 3.准备 前面使用 jedis,是通过 Jedis 对象里的各种方法来操作 redis 的.此处Spring 中则是通过 StringRedisTemplate 来操作 redis .最原始提供的类是 RedisTemplateStrin…

OceanBase:列存储

目录 1、列存储的定义 1、默认创建列存表 3、指定创建列存表 4、指定创建列存行存冗余表 5、行、列存储查询测试 1、列存储的定义 行存储&#xff08;Row-based Storage&#xff09;&#xff1a;行存储是以行为单位进行组织和存储数据。在这一模式下&#xff0c;数据库将…

C++ Primer 第五版 第十三章 拷贝控制

当定义一个类时&#xff0c;我们显式地或隐式地指定在此类型的对象拷贝、移动、赋值和销毁时做什么。一个类通过定义五种特殊的成员函数来控制这些操作&#xff0c;包括&#xff1a;拷贝构造函数&#xff08;copy constructor&#xff09;、拷贝赋值运算符&#xff08;copy-ass…

web自动化的断言和日志封装

断言 UI自动化常见的断言条件包括&#xff1a; 通过当前页面的URL地址通过当前页面的标题通过当前页面的提示文本信息通过当前页面的某些元素变化/显示 一句话总结&#xff1a;通过肉眼观察页面的变化检查。 【用代码模仿人的识别页面】 一般断言写一条就够了&#xff0c;如…

Visual Studio 智能代码插件:CodeGeeX

前言 在软件开发领域&#xff0c;高效的编程助手一直是提升开发者效率和质量的关键。 随着人工智能技术的不断发展&#xff0c;智能编程助手逐渐成为开发者们不可或缺的工具。其中&#xff0c;CodeGeeX作为一款专为Visual Studio设计的免费智能编程助手&#xff0c;凭借其强大…

goimghdr,一个有趣的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个有趣的 Python 库 - goimghdr。 Github地址&#xff1a;https://github.com/corona10/goimghdr 在图像处理和分析过程中&#xff0c;识别图像文件的类型是一个常见的需求。Python自带的imghdr…