内存泄漏
内存泄漏是什么?内存泄漏(Memory Leak)是指程序在分配内存后,由于某些原因未能正确释放,导致这部分内存无法被再次使用,直到程序结束或操作系统回收。内存泄漏会逐渐消耗系统资源,可能导致程序性能下降甚至崩溃。 如何避免内存泄漏?以下是一些常见的避免内存泄漏的方法: 使用 RAII(资源获取即初始化): RAII 是 C++ 中一种重要的资源管理技术,通过将资源(如动态分配的内存)绑定到对象的生命周期,确保资源在对象销毁时自动释放。 使用智能指针(如 std::unique_ptr、std::shared_ptr)管理动态内存,避免手动调用 delete。12345#include <memory>void safe_function() { std::unique_ptr<int> ptr = std::make_unique<int>(10); // 自动释放 // 无需手动 delete,ptr 离开作用域时自动销毁} 规范内存管理: 确保每个 new 都有对应的 delete,每个...
红黑树
红黑树介绍红黑树(Red-Black Tree)是一种自平衡的二叉搜索树,在插入和删除操作时通过特定的规则保持树的平衡,从而保证高效的查找、插入和删除操作。其时间复杂度通常为 ( O(\log n) ),适用于需要频繁动态更新的场景。 红黑树的性质红黑树在普通二叉搜索树(BST)的基础上增加了颜色属性(红或黑),并通过以下五条性质保持平衡: 节点颜色:每个节点要么是红色,要么是黑色。 根节点:根节点始终是黑色。 红色节点约束:红色节点的子节点必须是黑色(即红色节点不能连续)。 黑色路径等价:从根节点到每个叶子节点(或 NULL 节点)的路径上,黑色节点数量相同(称为黑色高度)。 叶子节点:所有叶子节点(通常是 NULL 节点)视为黑色。 这些性质确保红黑树的高度不会超过 ( 2 \log (n+1) ),从而保证高效的操作。 红黑树的操作 查找: 与普通二叉搜索树相同,根据键值比较沿树向下搜索,时间复杂度为 ( O(\log n)...
什么是多态?
编译时多态与运行时多态 1. 编译时多态含义 编译时多态(Static Polymorphism)是在编译阶段通过函数或操作的重载、模板等机制实现的多样化行为。 也称为静态多态,因为函数调用在编译时就绑定(静态绑定)。 实现方式 函数重载:根据参数类型或数量选择不同函数。 运算符重载:自定义运算符行为。 模板:通过模板参数生成不同类型的函数或类(模板特化)。 特点 效率高:编译时解析,无运行时开销。 类型固定:需要在编译时确定调用类型。 无虚函数:不涉及虚函数表(vtable,参考上下文)。 代码示例12345678910111213141516#include <iostream>// 函数重载void print(int x) { std::cout << "Int: " << x << "\n"; }void print(double x) { std::cout << "Double: " << x...
虚函数与虚函数表
C++ 中的多态、虚函数、虚函数表、虚函数表指针和虚析构函数以下是对 C++ 中多态、虚函数、虚函数表(vtable)、虚函数表指针(vptr)以及虚析构函数的详细介绍,使用 Markdown 格式,包含代码示例和 LaTeX 表示(若适用)。内容基于 C++ 的运行时多态机制,并结合上下文(如内存对齐、智能指针等)。 1. 多态含义多态(Polymorphism)是面向对象编程的核心特性,允许通过基类指针或引用调用派生类的行为。C++ 中的多态主要分为: 编译时多态:通过函数重载或模板实现。 运行时多态:通过虚函数和继承实现,依赖动态绑定。 运行时多态 通过基类指针或引用调用派生类的虚函数,根据对象的实际类型动态决定调用哪个函数。 依赖虚函数表和虚函数表指针实现。 数学表示对于基类指针 ( p ) 指向派生类对象,调用虚函数 ( f ),实际执行的函数为:[\text{Execute}(p \to f) = \text{Dispatch}(p.\text{vptr}, f)]其中,(\text{Dispatch}) 根据虚函数表解析具体函数地址。 2....
c++中的重写与重载
...
函数后面的const与noexcept
C++ 中函数后面的 const 和 noexcept 的含义在 C++ 中,函数声明或定义后添加的 const 和 noexcept 是函数修饰符,用于指定函数的行为和属性。 1. 函数后面的 const含义 成员函数限定符:const 出现在类成员函数的声明或定义后,表示该函数不会修改对象的非 mutable 成员变量。 承诺:调用该函数时,对象的状态(除 mutable 成员外)保持不变。 语义:用于声明“只读”成员函数,增强代码安全性。 实现机制 编译器将 const 成员函数的 this 指针视为 const T*(而非 T*),禁止修改非 mutable 成员。 可被 const 对象、引用或指针调用,而非 const 成员函数只能被非 const 对象调用。 代码示例12345678910111213141516171819#include <iostream>class MyClass { int x = 0; mutable int y = 0; // mutable 允许在 const 函数中修改public: ...
智能指针们与shared_ptr手撕
看柠檬微趣c++客户端一面面经,发现shared_ptr手撕不了一点,顺便再复习一下智能指针吧。(真是面试造火箭) 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192#include<cstddef>struct ControlBlock{ size_t shared_count;//引用计数 ControlBlock():shared_count(1){}};template <typename T>class Shared_ptr{private: T* ptr; ControlBlock* ctrl; void release()//一个私有的释放函数 { if(ctrl) ...
const和constexpr
constexpr 和 const 的区别在 C++ 中,const 和 constexpr 都用于定义常量,但它们的用途和行为有显著区别。 简单来说const可以是运行时变量也可以是编译时变量,而constexpr必须是编译时变量 而数组的大小这种就必须是编译时变量 以下是详细对比: 1. 定义和用途 **const**: 表示变量的值在初始化后不可修改(只读)。 可以用于运行时常量或编译时常量,具体取决于初始化方式。 适用场景:需要确保变量不被修改,但不一定要求编译时求值。 示例:123const int x = 10; // 编译时常量int y = 5;const int z = y; // 运行时常量(y 的值在运行时确定) **constexpr**: 表示变量或函数的值或结果必须在编译时可求值。 用于定义编译时常量或编译时计算的函数,确保结果在编译阶段确定。 适用场景:需要编译时常量(如数组大小、模板参数)或性能敏感的编译时计算。 示例:123constexpr int x = 10; // 编译时常量constexpr int square(int...
static
static 在 C++ 中的各种用法以下是 static 的主要用法,包括静态变量、静态全局变量、静态局部变量、静态函数、静态成员函数和静态成员变量的详细说明。 #include <iostream> #include <string> // 1. 静态全局变量(文件作用域) static int globalCount = 0; // 仅当前文件可见 // 2. 普通全局变量(对比) int nonStaticGlobal = 0; // 其他文件可通过 extern 访问 // 3. 静态函数(文件作用域) static void incrementGlobalCount() { globalCount++; std::cout << "Static globalCount: " << globalCount << "\n"; } class MyClass { private: // 4. 静态成员变量 ...
单例模式
单例模式(Singleton Pattern)是一种设计模式,确保一个类只有一个实例,并提供一个全局访问点。 在C++中,单例模式常用于需要全局唯一实例的场景,例如日志系统、配置管理器或数据库连接池。下面详细介绍其实现方法和作用。 单例模式的实现方法以下是几种常见的C++单例模式实现方式: 1. 懒汉式(Lazy Initialization)延迟初始化,在第一次使用时创建实例。需要注意线程安全问题。 1234567891011121314151617181920212223242526272829303132333435363738394041#include <iostream>#include <mutex>class Singleton {public: static Singleton* getInstance() { if (instance == nullptr) { // 第一次检查 std::lock_guard<std::mutex>...