内存管理:内存分区
核心要点速览 五大分区:栈(临时空间,自动管理)、堆(动态空间,手动管理)、全局 / 静态区(持久空间)、常量存储区(只读)、代码区(指令存储) 关键点:各分区存储内容 / 生命周期 / 分配方式、栈与堆的区别、const 变量存储位置、线程局部存储特性 补充:全局 / 局部 / 静态局部 / 静态全局变量的存储、生命周期及作用域差异 一、五大内存分区1. 栈(stack):函数调用的临时空间 存储内容:函数内局部变量(非 static)、函数参数、返回地址(调用后需返回的下一条指令地址)、寄存器上下文(函数调用时保存的 CPU 寄存器状态) 生命周期:随函数调用创建,函数执行结束后自动释放(无需手动干预) 特点: 分配效率:编译器通过移动栈顶指针(SP 寄存器)完成分配 / 释放,效率极高 内存特性:地址连续(栈帧结构),生长方向向下(从高地址向低地址扩展) 大小限制:默认固定(通常 1-8MB,可通过编译器 / 操作系统配置),超出则触发栈溢出 初始化:未初始化的局部变量值为 “垃圾值”(随机...
内存管理:RAII
核心要点速览 设计思想:资源获取与对象初始化绑定,资源释放与对象析构绑定(构造拿资源,析构放资源) 实现:封装资源为类成员,构造获取、析构释放,可选禁止拷贝 典型应用:智能指针、互斥锁、文件句柄、网络连接 优势:自动释放资源、异常安全、简化代码、保障资源独占 一、设计思想:资源对象的生命周期绑定RAII(Resource Acquisition Is Initialization)的本质是用对象生命周期管理资源: 对象构造时:自动获取资源(如分配内存、打开文件、加锁),确保资源获取成功后对象才有效; 对象析构时:自动释放资源(如释放内存、关闭文件、解锁),无论对象正常退出还是因异常销毁,析构函数都会执行。 二、实现原理 封装资源:定义类时,将待管理的资源(如指针、文件句柄、锁对象)声明为私有成员,禁止外部直接访问,确保资源只能通过类的接口管控; 强制获取资源:在构造函数中编写资源获取逻辑(如接收new的内存地址、调用fopen打开文件),若资源获取失败(如内存不足),直接抛出异常,避免构造 “无效对象”; 自动释放资源:在析构函数中编写资源释放逻辑(如delete内存、...
异常处理:异常传播与栈展开
核心要点速览 异常传播:无匹配catch时,异常逐层向上传递至调用者,直至捕获或触发std::terminate() 栈展开:传播过程中自动逆序销毁局部对象(按构造逆序),保障资源回收 规则:析构函数禁止抛异常(避免双重异常),未完全构造对象不执行析构 异常安全:依赖栈展开原子性 + RAII 机制,避免资源泄漏 补充:异常匹配优先精确 / 继承兼容,捕获const引用可避免异常切片 一、异常传播:从抛出点到捕获点的传递逻辑概念函数抛出异常且自身无匹配try-catch时,异常会沿函数调用栈逐层向上传播,依次遍历调用者上下文,直到被某个catch块捕获;若全程无捕获,程序调用std::terminate()终止(默认执行std::abort())。 传播流程 函数调用链:A→B→C,C 中抛出异常; C 无catch匹配,异常传播至 B; B 无catch匹配,继续传播至 A; A 的try块监控到异常,匹配catch执行处理; 若 A 仍无匹配,异常传播至main函数,最终未捕获则程序终止。 细节 异常传播时,被跳过函数中 “已执行但未进入try块” 的代码不再...
内存管理:动态内存
核心要点速览 动态内存:运行时手动分配,需手动释放(否则泄漏);new/delete 自动调用构造 / 析构,需与 new []/delete [] 严格匹配 智能指针(C++11+,<memory>):RAII 机制自动管理内存,unique_ptr(独占)、shared_ptr(共享,引用计数)、weak_ptr(解循环引用) 常见问题:内存泄漏(未释放)、野指针(未初始化)、悬空指针(指向已释放内存) 一、动态内存的分配与释放核心是 “分配 - 使用 - 释放” 闭环,C++ 推荐用 new/delete,需严格匹配使用。 1. C vs C++ 分配释放方式对比 对比维度 C(malloc/free) C++(new/delete) 类型安全 返回void*,需手动强转(不安全) 返回对应类型指针(无需转换,安全) 构造 / 析构 不调用(仅操作内存) 自动调用构造(new)/ 析构(delete) 数组支持 需手动计算总大小(n*sizeof(T)) 直接n...
异常处理:标准库异常与自定义异常
核心要点速览 标准库异常:以std::exception为基类,分逻辑错误(编译可避免)和运行时错误(运行不可预知)两大类,核心接口what()返回错误描述 自定义异常:推荐继承std::exception,重写what()(必须加noexcept),语义需贴合业务场景 核心原则:优先复用标准库异常,自定义异常兼顾兼容性与信息完整性,杜绝基本类型异常,避免滥用 一、标准库异常体系(<stdexcept>)结构标准库提供了一套统一的异常类继承体系,所有标准异常均派生自std::exception抽象基类。这种设计保证了异常处理的兼容性 —— 无论捕获具体异常还是统一捕获基类引用,都能有效处理,是面试中 “规范异常使用” 的核心考点。 基类:std::exception 接口:virtual const char* what() const noexcept; 纯虚函数,返回 C 风格错误描述字符串,子类必须重写该方法才能实例化。 特性:无参构造、拷贝构造、拷贝赋值均被标记为noexcept,确保异常对象自身的构造和拷贝过程不会抛出新异常(避免双重异常)。 异常分类...
异常处理:异常基础与语法
核心要点速览 异常处理三关键字:throw(抛出异常)、try(监控异常代码)、catch(捕获处理异常),核心是分离错误检测与处理 基本流程:try监控→throw抛异常→catch匹配处理;无匹配则异常传播,最终未捕获则程序终止 匹配规则:catch按声明顺序匹配,子类异常需在父类前捕获,catch(...)(万能捕获)必须放最后 异常类型:推荐类类型(标准库异常或自定义类),可携带详细信息;避免基本类型(语义模糊) 一、三个关键字一、throw(抛出异常) 作用:检测到不可处理的错误(如参数非法)时,主动抛出异常对象,中断当前执行,通知上层处理。 语法:throw 表达式;(表达式结果为异常对象)。 细节: 异常类型选择: 不推荐基本类型(如throw 1,语义模糊,无法区分错误类型); 推荐类类型(如标准库std::invalid_argument),可携带详细信息(如"文件路径不能为空")。 执行逻辑:throw后,当前函数中后续代码立即终止,进入异常传播阶段(寻找匹配catch)。 二、try(监控异常) 作用:包裹可能抛出异常的代码...
现代C++特性:Lambda表达式
核心要点速览 语法:[捕获列表](参数) mutable -> 返回类型 { 函数体 },必填:捕获列表 + 函数体 捕获方式:[=](值)、[&](引用)、[=, &x](混合)、[this](类内)、[x=std::move(y)](C++14 移动捕获) 陷阱:悬垂引用 /this、mutable误用、多 return 未显式指定返回类型、STL 排序谓词非严格弱序 特性:无捕获转函数指针、有捕获需std::function包装、C++14 泛型、C++17constexpr/[*this] 用途:简化 STL 算法参数(sort/find_if),替代短小的临时函数和仿函数 一、捕获列表1. 捕获方式 捕获方式 说明 [=] 捕获时机为 Lambda 创建时,仅拷贝实际使用的外部变量,外部变量后续修改不会影响副本 [&] 默认引用捕获所有用到的外部变量,优点是无拷贝开销,但严禁返回带此捕获的 Lambda(极易产生悬垂引用) [=, &x] 默认值捕获,仅 x 显式按引用捕获,显式捕...
现代C++特性:右值引用和移动语义
核心要点速览 左值 vs 右值:左值有持久地址(可 & 取址),右值是临时对象 / 字面量(不可 & 取址) 右值引用(T&&):绑定右值,延长其生命周期,支持修改绑定对象 移动语义:通过移动构造 / 赋值转移资源(而非拷贝),提升性能(避免深拷贝) std::move:将左值转为右值引用(仅转换,不移动资源),原对象不应再使用 完美转发:std::forward 保持参数左值 / 右值属性,用于模板传递参数 一、左值与右值:值的分类1. 左值 定义:可放在赋值左侧,有持久内存地址,生命周期较长(如变量、函数返回的左值引用)。 特征:可被&取址(&a合法),可被赋值(a = 5合法)。 示例:int x = 10;(x 是左值)、int& func()(返回左值引用,是左值)。 2. 右值 定义:只能放在赋值右侧,无持久内存地址(或地址无意义),生命周期短暂。 分类: 纯右值:字面量(5、"hello")、表达式结果(x + y)、临时对象(func()返回非引用时)。...
现代C++特性:类型推导
核心要点速览 auto:基础推导忽略顶层 const / 引用,C++14 拓展至函数返回值与 lambda 参数,有明确使用限制。 decltype:精确保留类型(含 const / 引用),支持表达式推导,双层括号是推导左值引用的关键。 模板类型推导:分按值 / 按引用 / 万能引用三类场景,需特殊处理数组与函数名,核心是 “实参到形参的类型映射”。 进阶场景:decltype(auto) 结合两者优势,auto&& 适配多值类别,万能引用需搭配 std::forward 实现完美转发。 区别:auto 侧重 “简化声明”,decltype 侧重 “精确获取”,模板推导侧重 “参数适配”。 一、auto:自动推导变量类型用途是简化长类型声明,C++14 拓展了适用场景,推导逻辑聚焦 “忽略顶层修饰,保留底层约束”。 1. 推导规则 必须初始化:编译器依赖初始化表达式推导,未初始化编译报错(如auto x;报错)。 顶层 const / 引用忽略:变量本身的 const 和引用被舍弃,底层 const(指向常...
文件IO:文件操作
核心要点速览 文本文件:>>/<<、getline()读写,自动转换换行符,适配人类可读数据(日志、配置)。 二进制文件:read()/write()操作原始字节流,适配非文本数据(图片、结构体),效率更高。 文件指针:seekg()/seekp()定位、tellg()/tellp()获取位置,支持随机访问。 关键:模式区分、读写混用问题、字节对齐、缓冲区刷新、跨平台兼容核心点。 一、文本文件:读写逻辑与易错文本文件以字符编码(ASCII/UTF-8)存储,读写时自动处理换行符转换(如 Windows 下\n→\r\n),核心关注 “读写一致性” 与 “缓冲区问题”。 1. 读写方法(1)写入操作(ofstream)12345ofstream ofs("text.txt", ios::out | ios::app); // 追加模式if (!ofs) return -1; // 检查打开失败ofs << "姓名:Tom" << endl; ...
