力扣 LCR训练计划2(剑指 Offer 22. 链表中倒数第k个节点)-140

news2024/12/4 16:04:59

LCR训练计划2(剑指 Offer 22. 链表中倒数第k个节点)-140 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* trainingPlan(ListNode* head, int cnt) {
        ListNode* cur = NULL;
        ListNode* pre = head;
        while(pre!=NULL)
        {
            ListNode* t = pre->next;
            pre->next = cur;
            cur = pre;
            pre = t;
        }
        /*以上是反转链表操作
        定义ListNode指针类型的变量temp记录反转后cur的位置,因为后续操作cur的位置会发生变化,此时的cur为反转后链表的头节点,
        因为后续找到倒数第cnt个节点后要再进行一次反转,因为题目要找的是正常顺序链表的倒数第cnt个节点
        此时的反转链表只是为了方便找到倒数第cnt的节点位置*/
        ListNode* temp = cur;
        //while循环用来找到正数第cnt节点的位置,因为我们已经将链表反转了,从题意倒数变成了正数
        while(cnt>1)
        {
            cur=cur->next;
            cnt--;
        }
        //循环过后,cur已经找到了倒数第cur节点的位置,定义ListNode指针类型的变量temphead记录倒数第cur节点的位置
        ListNode* temphead = cur;
        /*以下是将反转后的链表再一次反转的操作,再一次反转过后链表变为正常顺序的链表,
        最后根据题意返回temphead及往后的所有节点*/
        ListNode* cur1 = NULL;
        ListNode* pre1 = temp;
        while(pre1!=NULL)
        {
            ListNode* t1 = pre1->next;
            pre1->next = cur1;
            cur1 = pre1;
            pre1 = t1;
        }
        return temphead;
    }
};

每日问题

C++循环引用指的是什么,在使用过程当中需要注意什么问题

C++中的循环引用

循环引用(Cyclic Reference)通常指的是两个或多个对象相互引用,形成一个闭环,使得这些对象之间无法被销毁或释放,导致内存泄漏或资源未被及时回收。这种情况最常见于使用指针或智能指针的场景中,特别是在涉及到对象之间相互持有指针或引用时。

循环引用的例子:

考虑一个简单的 C++ 例子,假设我们有两个类 A 和 B,它们通过指针互相引用:

class B; // 前向声明

class A {
public:
    std::shared_ptr<B> b_ptr; // A 持有 B 的 shared_ptr
};

class B {
public:
    std::shared_ptr<A> a_ptr; // B 持有 A 的 shared_ptr
};

在这个例子中:

类 A 有一个 shared_ptr 指向类 B 的实例。

类 B 也有一个 shared_ptr 指向类 A 的实例。

如果在程序中创建了 A 和 B 的实例,并且它们通过 shared_ptr 互相引用,当这两个对象超出作用域时,由于 shared_ptr 的引用计数机制,它们互相持有对方,导致它们的引用计数永远不为零。因此,这些对象的析构函数永远不会被调用,从而导致内存泄漏。

循环引用的具体问题

1.内存泄漏:

循环引用的最大问题就是内存泄漏。在智能指针(如 std::shared_ptr)的情况下,引用计数机制会不断增加,导致内存无法被释放。

2.资源无法释放:

除了内存泄漏,循环引用还可能导致其他资源(如文件句柄、数据库连接等)无法及时释放,影响程序性能和稳定性。

3.性能问题:

循环引用会影响垃圾回收或引用计数机制的正常工作,使得它们无法有效地管理资源,可能导致程序资源消耗过多或响应变慢。

避免循环引用的策略

1.弱指针(std::weak_ptr):

如果我们希望避免循环引用,可以使用 std::weak_ptr 替代 std::shared_ptr。std::weak_ptr 不会增加引用计数,也不会阻止对象被销毁。它可以用来观察一个对象,而不持有它。

例如,可以将其中一个指针改为 weak_ptr 来打破循环引用:

class A;

class B {
public:
    std::weak_ptr<A> a_ptr;  // 使用 weak_ptr 避免循环引用
};

class A {
public:
    std::shared_ptr<B> b_ptr;
};

在这种情况下,

B 类持有 A 类的弱引用,这样当 A 被销毁时,不会阻止 B 的析构,同时 A 依然可以安全地持有 B 的 shared_ptr。

2.手动管理资源:

如果循环引用不能避免(例如某些设计模式中确实需要双向引用),可以选择手动管理资源释放,确保在适当的时候解除相互引用。比如在对象销毁前,将智能指针置空或重新设置。

3.避免不必要的双向引用:

在设计时,尽量避免不必要的双向引用。例如,可以考虑将其中一个对象的引用设计为单向引用,而不是双向引用。这样就可以避免引起复杂的引用关系。

4.设计模式:观察者模式:

如果存在双向引用的需求,考虑使用观察者模式来解耦对象间的关系。在这种模式中,一个对象(通常是“主题”)可以有多个观察者(其他对象),而不需要在两个对象之间建立直接的循环引用关系。

5.手动释放资源:

如果确实存在循环引用,且无法使用 weak_ptr 等方法来解决,可以通过手动解除循环引用(例如,在合适的时机将指针重置为 nullptr)来避免资源泄漏。

总结

循环引用 发生在对象通过智能指针(如 shared_ptr)或裸指针互相引用,导致它们无法被销毁,造成内存泄漏。

解决方法 主要是使用 std::weak_ptr 来打破循环引用,或者通过手动解除循环引用来管理资源。

在 C++ 中,避免循环引用是一个重要的设计考虑,特别是在复杂的对象关系和资源管理场景中。

new或malloc在申请空间时,超出可申请的大小就会分配异常,可申请的大小是多少

在 C++ 中,new 或 C 中的 malloc 等内存分配函数,如果申请的内存超过系统能分配的最大内存大小,通常会出现异常或错误。这个最大可分配的内存大小取决于多个因素:

1.操作系统和架构的限制:

在 32 位系统上,通常最多能分配的内存是 4GB(不过,由于操作系统通常会把一些内存空间保留给内核,用户空间可能会少于 4GB),每个进程的最大虚拟内存空间通常在 2GB 到 3GB 之间。

在 64 位系统上,理论上支持的内存大小可以达到几 EB(Exabyte,亿亿字节),但实际上,系统能分配的内存通常受硬件(物理内存)、操作系统和其他限制的影响,通常是几 TB 或者更多。

2.可用物理内存和虚拟内存:

malloc 或 new 在分配内存时,操作系统会尝试为进程分配一个足够大的虚拟内存块。如果虚拟内存不足,或者物理内存不足以满足请求,分配会失败。

3.片化:

内存碎片化也会影响内存分配的成功与否。即使总的可用虚拟内存很大,如果内存已经被分割成许多小块,可能无法分配一个大的连续内存块。

错误和异常处理:

        C++:

                如果 new 无法分配内存,会抛出 std::bad_alloc 异常。你可以使用 try-catch 块捕获这个异常。

try {
    int* arr = new int[10000000000]; // 试图申请一个非常大的数组
} catch (const std::bad_alloc& e) {
    std::cerr << "内存分配失败: " << e.what() << std::endl;
}
        C:

                如果 malloc 或 calloc 无法分配内存,它们会返回 NULL,并且通常会设置 errno 为 ENOMEM。

实际可申请的大小:

        这个大小通常依赖于:

                系统的总物理内存和虚拟内存

                系统的内存分配策略

                操作系统的配置(例如,最大进程内存限制)

                程序本身的内存使用情况

在大多数现代操作系统中,单个进程的虚拟地址空间在 64 位系统上非常大,但要注意物理内存的限制和操作系统的配置可能会导致超出物理内存时出现分配失败或严重的性能下降。

总结:

对于 new 和 malloc,具体能分配多少内存受到操作系统、硬件架构、物理内存、虚拟内存空间以及内存碎片等多方面因素的限制。

在 64 位操作系统上,通常可分配的内存大小非常大,然而,最终是否能成功分配内存也取决于具体的系统和当前的内存使用状况。

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

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

相关文章

亚马逊云(AWS)使用root用户登录

最近在AWS新开了服务器&#xff08;EC2&#xff09;&#xff0c;用于学习&#xff0c;遇到一个问题就是默认是用ec2-user用户登录&#xff0c;也需要密钥对。 既然是学习用的服务器&#xff0c;还是想直接用root登录&#xff0c;下面开始修改&#xff1a; 操作系统是&#xff1…

Android笔记【12】脚手架Scaffold和导航Navigation

一、前言 学习课程时&#xff0c;对于自己不懂的点的记录。 对于cy老师第二节课总结。 二、内容 1、PPT介绍scaffold 2、开始代码实操 先新建一个screen包&#xff0c;写一个Homescreen函数&#xff0c;包括四个页面。 再新建一个compenent包&#xff0c;写一个displayText…

HookVip4.0.3 | 可解锁各大应用会员

HookVip是一款可以解锁会员的模块工具&#xff0c;需要搭配相应框架结合使用。这款插件工具支持多种框架如LSPosed、LSPatch、太极、应用转生等&#xff0c;并且完全免费&#xff0c;占用内存小。支持的软件包括now要想、神奇脑波、塔罗牌占卜、爱剪辑、人人视频、咪萌桌面宠物…

猎板 PCB特殊工艺:铸就电子行业核心竞争力新高度

在当今竞争激烈且技术驱动的电子制造领域&#xff0c;印制电路板&#xff08;PCB&#xff09;作为电子产品的关键基石&#xff0c;其特殊工艺的发展水平直接影响着整个行业的创新步伐与产品品质。猎板 PCB 凭借在厚铜板、孔口铺铜、HDI 板、大尺寸板以及高频高速板等特殊工艺方…

【教学类-43-25】20241203 数独3宫格的所有可能-使用模版替换(12套样式,空1格-空8格,每套510张,共6120小图)

前期做数独惨宫格的所有排列&#xff0c;共有12套样式&#xff0c;空1格-空8格&#xff0c;每套510张&#xff0c;共6120小图&#xff09; 【教学类-43-24】20241127 数独3宫格的所有可能&#xff08;12套样式&#xff0c;空1格-空8格&#xff0c;每套510张&#xff0c;共6120…

Redis+Caffeine 多级缓存数据一致性解决方案

RedisCaffeine 多级缓存数据一致性解决方案 背景 之前写过一篇文章RedisCaffeine 实现两级缓存实战&#xff0c;文章提到了两级缓存RedisCaffeine可以解决缓存雪等问题也可以提高接口的性能&#xff0c;但是可能会出现缓存一致性问题。如果数据频繁的变更&#xff0c;可能会导…

echarts地图立体效果,echarts地图点击事件,echarts地图自定义自定义tooltip

一.地图立体效果 方法1:两层地图叠加 实现原理:geo数组中放入两个地图对象,通过修改zlevel属性以及top,left,right,bottom形成视觉差 配置项参考如下代码: geo: [{zlevel: 2,top: 96,map: map,itemStyle: {color: #091A51ee,opacity: 1,borderWidth: 2,borderColor: #16BAFA…

D87【python 接口自动化学习】- pytest基础用法

day87 pytest运行参数 -m -k 学习日期&#xff1a;20241203 学习目标&#xff1a;pytest基础用法 -- pytest运行参数-m -k 学习笔记&#xff1a; 常用运行参数 pytest运行参数-m -k pytest -m 执行特定的测试用例&#xff0c;markers最好使用英文 [pytest] testpaths./te…

总结拓展十七:特殊采购业务——委外业务

SAP中委外采购业务&#xff0c;又称供应商分包&#xff08;或外协、转包、、外包、托外等&#xff09;&#xff0c;是企业将部分生产任务委托给外部供应商/集团其他分子公司完成的一种特殊采购业务模式。 委外业务主要有2大类型&#xff0c;分别是标准委外&#xff08;委外采购…

ESP8266作为TCP客户端或者服务器使用

ESP8266模块&#xff0c;STA模式&#xff08;与手机搭建TCP通讯&#xff0c;EPS8266为服务端&#xff09;_esp8266作为station-CSDN博客 ESP8266模块&#xff0c;STA模式&#xff08;与电脑搭建TCP通讯&#xff0c;ESP8266 为客户端&#xff09;_esp8266 sta 连接tcp-CSDN博客…

ATTCK红队评估实战靶场(四)

靶机链接&#xff1a;http://vulnstack.qiyuanxuetang.net/vuln/detail/6/ 环境搭建 新建两张仅主机网卡&#xff0c;一张192.168.183.0网段&#xff08;内网网卡&#xff09;&#xff0c;一张192.168.157.0网段&#xff08;模拟外网网段&#xff09;&#xff0c;然后按照拓补…

C 语言 “神秘魔杖”—— 指针初相识,解锁编程魔法大门(一)

文章目录 一、概念1、取地址操作符&#xff08;&&#xff09;2、解引用操作符&#xff08;*&#xff09;3、指针变量1、 声明和初始化2、 用途 二、内存和地址三、指针变量类型的意义1、 指针变量类型的基本含义2、 举例说明不同类型指针变量的意义 四、const修饰指针1、co…

封装loding加载动画的请求

图片 /*** Loading 状态管理类*/ export class Loading {constructor(timer300) {this.value falsethis.timer timer}/*** 执行异步操作并自动管理 loading 状态* param {Promise|Function|any} target - Promise、函数或其他值* returns {Promise} - 返回请求结果*/async r…

人形机器人训练、机器臂远程操控、VR游戏交互、影视动画制作,一副手套全部解决!

广州虚拟动力基于自研技术推出了多节点mHand Pro动捕数据手套&#xff0c;其最大的特点就是功能集成与高精度捕捉&#xff0c;可以用于人形机器人训练、机器臂远程操控、VR游戏交互、影视动画制作等多种场景。 一、人形机器人训练 mHand Pro动捕数据手套双手共装配16个9轴惯性…

Nginx Web服务器管理、均衡负载、访问控制与跨域问题

Nginx Web 服务器的均衡负载、访问控制与跨域问题 Nginx 的配置 1. 安装Nginx 首先安装Nginx apt install nginx -ycaccpurgatory-v:~$ sudo apt install nginx [sudo] password for cacc: Reading package lists... Done Building dependency tree... Done Reading state i…

Bert+CRF的NER实战

CRF&#xff08;条件随机场-Conditional Random Field&#xff09; 原始本文&#xff1a;我在北京吃炸酱面 标注示例&#xff08;采用BIO标注方式&#xff09;&#xff1a; 我O在O北B-PLA京I-PLA吃O炸B-FOOD酱I-FOOD面I-FOOD CRF&#xff1a; 目的&#xff1a;提出一些不可能…

C++语法·识

人生建议&#xff1a;请手机反省一下&#xff0c;为什么总拉着我熬夜。 目录 STL简介 string类容器一 auto&#xff08;自动声明类型&#xff09; 简介&#xff1a; 特点 范围for&#xff08;语法糖&#xff09; 简介 特点 string string类的常见接口 1.构造 2.容…

蓝桥杯准备训练(lesson1,c++方向)

前言 报名参加了蓝桥杯&#xff08;c&#xff09;方向的宝子们&#xff0c;今天我将与大家一起努力参赛&#xff0c;后序会与大家分享我的学习情况&#xff0c;我将从最基础的内容开始学习&#xff0c;带大家打好基础&#xff0c;在每节课后都会有练习题&#xff0c;刚开始的练…

【开源】A059-基于SpringBoot的社区养老服务系统的设计与实现

&#x1f64a;作者简介&#xff1a;在校研究生&#xff0c;拥有计算机专业的研究生开发团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看项目链接获取⬇️&#xff0c;记得注明来意哦~&#x1f339; 赠送计算机毕业设计600个选题ex…

winform跨线程更新界面

前言&#xff1a; 大家好&#xff0c;我是上位机马工&#xff0c;硕士毕业4年年入40万&#xff0c;目前在一家自动化公司担任软件经理&#xff0c;从事C#上位机软件开发8年以上&#xff01;我们在开发C#程序的时候&#xff0c;有时候需要在非Ui主线程更新界面&#xff0c;为了…