C++学习第十课:指针陷阱与引用传递(阶段练习题)

news2024/11/23 16:53:42

在这里插入图片描述

C++学习第十课:指针陷阱与引用传递

在C++中,指针和引用是两个强大的特性,但它们也可能导致一些常见的错误。本课将深入探讨使用指针时可能遇到的问题,并介绍引用的概念和使用方式。

大纲标题与代码详解

1. 日常使用指针容易犯的错误

  • 内存泄漏:未释放动态分配的内存。
int* ptr = new int(100);
// 忘记delete
  • 指针无效:指针指向的内存已经被释放。
int* ptr = new int(100);
delete ptr;
// ptr变成野指针(悬挂指针),再访问*ptr是未定义行为
  • 悬浮指针:指针被重新赋值前未置空。
int* ptr = new int(100);
int* oldPtr = ptr;
delete ptr;
ptr = nullptr; // ptr置空,oldPtr仍是悬挂指针

2. 检查 new 发出的分配请求是否得到满足

  • 使用 new (std::nothrow) 避免异常,检查返回值。
int* ptr = new (std::nothrow) int(100);
if (ptr == nullptr) {
    std::cerr << "Memory allocation failed" << std::endl;
}

3. 引用是什么

  • 引用的基本概念:引用是别名,指向一个已存在的变量。
int original = 10;
int& ref = original; // ref是original的引用
ref = 20; // 修改引用,original的值也变为20

4. 按引用向函数传递参数

  • 避免不必要的复制:尤其是对于大型对象或数组。
void printVector(std::vector<int>& vec) {
    for (int num : vec) {
        std::cout << num << " ";
    }
    std::cout << std::endl;
}
  • 常量引用:防止函数内部修改参数值。
void printValue(const int& value) {
    std::cout << value << std::endl;
}

5. 引用与指针的区别

  • 安全性:引用必须在定义时就被初始化,不能是空的。
  • 语法:引用在语法上更接近变量的使用,而指针则需要显式地使用解引用操作符 *

6. 引用在函数返回中的应用

  • 通过引用返回多个值或返回大型对象,避免复制。
std::pair<int&, int&> getValues(int& a, int& b) {
    return std::make_pair(a, b);
}

7. 引用在类设计中的应用

  • 使用引用成员函数来避免对象复制。
class MyClass {
public:
    void updateValue(int& value) {
        value *= 2;
    }
};

8. const 关键字与引用

  • 使用 const 修饰引用,确保引用不会改变所绑定的变量的值。
void print(const int& value) {
    // value不可修改
    std::cout << value << std::endl;
}

练习题一:使用指针和动态内存管理实现简单内存池

目的:练习动态内存分配、指针操作和内存池概念。

任务

  1. 创建一个名为 MemoryPool 的类,模拟一个简单的内存池。
  2. 类应该能够分配和释放内存。
  3. 分配内存时,应该检查是否有足够的空间,如果没有,则分配更多内存。
  4. 提供一个方法来访问分配的内存块。

示例代码框架

#include <iostream>
#include <vector>

class MemoryPool {
private:
    std::vector<char> memory; // 使用字符向量模拟内存
    size_t blockSize; // 每个内存块的大小

public:
    MemoryPool(size_t size) : blockSize(size) {}

    // 分配内存块
    void* allocateBlock() {
        if (memory.size() < blockSize) {
            // 如果当前内存不足以分配一个块,则扩展内存
            memory.resize(memory.size() + blockSize);
        }
        // 返回当前内存的末尾指针,模拟分配
        return &memory[memory.size() - blockSize];
    }

    // 释放内存块(简单起见,这里不实现真正的释放逻辑)
    void releaseBlock(void* ptr) {
        // 检查ptr是否在memory范围内,并执行必要的释放逻辑
    }

    // 获取内存块的数据(用于测试)
    char* getData(void* ptr) {
        return static_cast<char*>(ptr);
    }
};

int main() {
    MemoryPool pool(10); // 创建一个每个块大小为10的内存池

    void* block1 = pool.allocateBlock();
    void* block2 = pool.allocateBlock();

    // 使用getData方法测试访问内存块
    *pool.getData(block1) = 'A';
    *(pool.getData(block1) + 1) = '\0';

    std::cout << "Block 1 contains: " << pool.getData(block1) << std::endl;

    pool.releaseBlock(block1);
    pool.releaseBlock(block2);

    return 0;
}

练习题二:实现一个函数,通过引用传递参数并修改原值

目的:练习引用的使用,理解引用与指针的区别。

任务

  1. 编写一个函数 increment,它接受一个整数的引用,并将其值加一。
  2. main 函数中测试 increment 函数,确保它能够修改传入的整数变量的值。

示例代码框架

#include <iostream>

// 函数通过引用修改整数的值
void increment(int& value) {
    value += 1;
}

int main() {
    int number = 10;
    std::cout << "Before increment: " << number << std::endl;
    increment(number);
    std::cout << "After increment: " << number << std::endl;

    return 0;
}

注意

  • increment 函数中,int& value 表示 value 是一个整数的引用。
  • 修改 value 的值将直接影响传递给函数的原始变量。

结语

在本课中,我们学习了使用指针时可能遇到的问题,包括内存泄漏、无效指针和悬浮指针。同时,我们深入了解了引用的概念和应用,包括如何通过引用传递参数以避免不必要的复制,以及如何在函数中使用引用返回多个值。

引用提供了一种安全、高效的方式来传递变量,而不需要担心复制大型对象或数组的性能开销。正确使用指针和引用,可以帮助我们编写出更加高效和安全的C++程序。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS的布局模式

前言&#xff1a; 我们可以看到京东的官网上的一些例子&#xff08;如下图&#xff09;&#xff0c;在同一排中能够存在多个div&#xff0c;这是通过布局方式&#xff08;例如浮动&#xff09;来实现的。 CSS传统的布局模式&#xff1a; <1>普通流&#xff08;又称之为标…

mysql UNION 联合查询

mysql UNION 联合查询 业务需要拉数据&#xff0c;这里需要对查询不同格式的数据进行组装&#xff0c;此处采用联合查询 注意1&#xff1a;null as 设备关爱 &#xff0c;结果为null&#xff0c;表头为设备关爱 注意2&#xff1a; UNION 或者 UNION ALL 联合查询自行选用 注意3…

OpenTK:安装和说明

OpenTK介绍 OpenTK是一个开源、跨平台的游戏开发库&#xff0c;由MonoGame团队创建。它为C#开发者提供了一个简单易用的接口&#xff0c;以便使用OpenGL、OpenAL和OpenCL进行3D渲染、音频处理和并行计算。OpenTK的目标是提供一个一致且高效的框架&#xff0c;让开发者能够专注于…

经典文献阅读之--SurroundOcc(自动驾驶的环视三维占据栅格预测)

0. 简介 环视BEV已经是很多场景中需要的功能&#xff0c;也是视觉代替激光雷达的有效解决方案&#xff0c;而《SurroundOcc: Multi-camera 3D Occupancy Prediction for Autonomous Driving》一吻则代表了这个领域的SOTA算法&#xff0c;文中通过多帧点云构建了稠密占据栅格数据…

windows下安装onlyoffice

文章目录 1、 安装ErLang2、 安装rabbitmq3、 安装postgresql4、 安装onlyoffice(社区版) 1、 安装ErLang 下载地址&#xff1a;https://erlang.org/download/otp_win64_24.2.exe opt_wind64_24.2.exe 直接运行&#xff0c;一步一步安装 2、 安装rabbitmq 下载地址&#xf…

若依:Linux Centos 7.9 安装部署RuoYi前后端集成版

目录 1.虚拟机操作系统版本 2.删除旧的jdk 3.下载JDK 17 &#xff1a; 4.下载 mvn 3.9.6&#xff1a; 5.下载mysql:5.7.44版本 6.git下载若依&#xff1a; 7.修改数据库连接&#xff1a; 8.mvn 清理和打包 9.启动若依&#xff1a; 1.虚拟机操作系统版本 2.删除旧的jd…

Qt QThreadPool线程池

1.简介 QThreadPool类管理一个QThread集合。 QThreadPool管理和重新设计单个QThread对象&#xff0c;以帮助降低使用线程的程序中的线程创建成本。每个Qt应用程序都有一个全局QThreadPool对象&#xff0c;可以通过调用globalInstance来访问该对象。 要使用其中一个QThreadPool…

XY_RE复现(四)舔狗四部曲

一&#xff0c;我的白月光 BOOK框还叉不掉&#xff0c;主函数很长 int __cdecl main(int argc, const char **argv, const char **envp) {__m128 si128; // xmm6__int128 *v4; // raxint v5; // r13dunsigned int v6; // ecx__m128 v7; // xmm0_DWORD *v8; // raxHMODULE Modu…

ROS 2边学边练(37)-- 使用时间参数(C++)

前言 在前几篇内容中&#xff0c;我们已经了解过了tf2广播、tf2监听&#xff0c;并且还了解了如何添加一个坐标系到tf2树图中&#xff0c;以及如何查看坐标系间的转换情况。实际上&#xff0c;是通过lookupTransform函数来查找的&#xff0c;这个函数允许我们查找所有的转换数据…

数据结构中的栈(C语言版)

一.栈的概念 栈是一种常见的数据结构&#xff0c;它遵循后进先出的原则。栈可以看作是一种容器&#xff0c;其中的元素按照一种特定的顺序进行插入和删除操作。 压栈&#xff1a;栈的插入操作叫做进栈/压栈/入栈&#xff0c;入数据在栈顶。 出栈&#xff1a;栈的删除操作叫做…

品牌百度百科词条需要什么资料?

品牌百度百科词条是一个品牌的数字化名片&#xff0c;更是品牌历史、文化、实力的全面展现。 作为一个相当拿得出手的镀金名片&#xff0c;品牌百度百科词条创建需要什么资料&#xff0c;今天伯乐网络传媒就来给大家讲解一下。 一、品牌基本信息&#xff1a;品牌身份的明确 品…

神之浩劫2下载教程 MOBA新游神之浩劫2在哪下载/怎么下载

《神之浩劫2Smite 2》重新定义了MOBA游戏的征服模式&#xff0c;为玩家带来更多的互动和进展。最近的开发者深度挖掘展示了游戏地图的全新设计&#xff0c;既简化了基本操作&#xff0c;又丰富了游戏选择。游戏中的敌人也有了新的进展方式。例如&#xff0c;击败火巨人和金之怒…

兄弟们,哪一家做智慧校园的公司比较靠谱?

开发技术参数 1、使用springboot框架Javavue2 2、数据库MySQL5.7 3、移动端小程序使用小程序原生语言开发 4、电子班牌固件安卓7.1&#xff1b;使用Java Android原生 5、elmentui &#xff0c;Quartz&#xff0c;jpa&#xff0c;jwt 6、SaaS云平台&#xff0c;私有云部署…

社区新零售:重构邻里生活圈,赋能美好未来

新时代的邻里脉动 在城市的肌理中&#xff0c;社区作为生活的基本单元&#xff0c;正经历一场由新零售引领的深刻变革。社区新零售&#xff0c;以其独特的商业模式、创新的技术手段和以人为本的服务理念&#xff0c;重新定义了社区商业的边界&#xff0c;重构了邻里生活的形态…

hive-row_number() 和 rank() 和 dense_rank()

row_number() 是无脑排序 rank() 是相同的值排名相同&#xff0c;相同值之后的排名会继续加&#xff0c;是我们正常认知的排名&#xff0c;比如学生成绩。 dense_rank()也是相同的值排名相同&#xff0c;接下来的排名不会加。不会占据排名的坑位。

【全开源】Java上门老人护理老人上门服务类型系统小程序APP源码

功能&#xff1a; 服务分类与选择&#xff1a;系统提供详细的老人护理服务分类&#xff0c;包括日常照护、康复训练、医疗护理等&#xff0c;用户可以根据老人的需求选择合适的服务项目。预约与订单管理&#xff1a;用户可以通过系统预约护理服务&#xff0c;并查看订单详情&a…

2024年618哪些数码家电值得入手?热门家电好物抢先看!

618购物狂欢节即将来临&#xff0c;这是一年一度的大促销活动&#xff0c;家电和数码产品在这个时间段内通常都会有优惠和折扣。但随着产品的多样化&#xff0c;很多时候一款产品就有多款品牌&#xff0c;在这不同品牌又各自擅长不同的东西&#xff0c;看着眼花缭乱。今天我就给…

有没有一种可能性,你不投递简历,让HR主动联系你

你是否觉得自己得主动给某个公司投递了简历,他们才会联系你,亦或者是自己得主动在招聘APP上联系那个BOSS,他才会反过来跟你说话,又或者是你千方百计的跟他打招呼了,还是没有回应,这一节有可能让你明白,有时候是可以,你不主动,他也会主动联系你的。 目录 1 简历是如何…

IDEA 编码规约扫描 Code inspection did not find anything to report.

IDEA安装了Alibaba Java Coding Guidelines插件&#xff0c;却看不到规约检查结果。手动进行编码规约扫描&#xff0c;弹窗提示“Code inspection did not find anything to report.”&#xff1a; 这种情况是因为代码文件所在的目录被标记成了测试文件&#xff08;Test Source…

EOCR-SS-05W电子式过电流继电器 0.5-6A 施耐德韩国三和

三和EOCR株式会社是韩国的电动机保护器生产企业&#xff0c;公司由金仁锡博士&#xff08;施耐德电气集团韩国执行官&#xff09;于1981年建立。 2001年&#xff0c;为了把企业发展成性的、战略性企业&#xff0c;随后加入了法国施耐德电气集团公司。 EOCR主要产品有电子式电…