• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2022-03-01 21:44 Aet 隐藏边栏 |   抢沙发  11 
文章评分 1 次,平均分 5.0

查看内存泄露的方法

Visual Studio CRT 库方法

  1. 这是最直接的内置方法,特别适合在开发调试阶段快速发现问题

Visual Leak Detector (VLD)

  1. 在包含main()函数的源文件中包含头文件即可:#include <vld.h>
  2. Debug模式下运行程序,泄漏报告会输出到Visual Studio的“输出”窗口

Visual Studio 内存性能分析器

  1. 调试-性能探查器
  2. 对于Release版本中出现的泄漏,或者需要分析内存使用趋势时,这个内置的性能分析工具非常强大

进阶方案

  1. 重载 new/delete
    1. 通过全局重载newdelete运算符,可以记录每一次内存分配和释放的详细信息(如大小、指针地址、调用堆栈等)

其他

如何实现一个高效的比较字符串的方法(非n方)

  1. 位图编码比较
  2. KMP算法
  3. Boyer-Moore算法
  4. Rabin-Karp算法

用一个类的空对象指针,去调用普通函数和虚函数

  1. 普通函数
    1. 不访问数据成员,可以
    2. 访问数据成员,崩溃
  2. 虚函数
    1. 崩溃

this指针

  1. this指针确实指向当前对象在内存中的首地址

对象的vptr

  1. vptr类型

  1. vs里面局部变量观察vptr成员,发现类型都是void*
    1. 虚函数表在内存中本质上是一个函数指针数组,而编译器在组织和访问这个数组时,并不关心每个函数指针具体的签名(包括返回类型和参数),它只关心这些指针在内存中的顺序和地址
  2. vptr位置
    1. 通常位于对象内存布局的开头。这是最高效的访问方式,但C++标准并未强制规定,编译器实现可能有差异
  3. RTTI存储位置
    1. 存储在虚函数表(vtable)之前的某个固定偏移处(通常是一个负偏移),与vtable紧密关联
      1. MSVC编译器下,这个负偏移量通常是4字节(32位)或8字节(64位),具体对应的是vptr指针向前偏移一个指针大小的位置来获取RTTICompleteObjectLocator的地址

虚函数表

  1. 本质
    1. 虚函数表可以理解为一个函数指针数组
    2. 这个数组在编译时由编译器静态创建,并存储在程序的只读数据段
    3. 数组中的每个元素,简单来说就是一个内存地址,指向一段可执行代码的起始位置
      这个地址本身并不携带任何关于函数参数和返回类型的信息,它就是一个数字
  2. 编译期的类型安全
    1. 类型安全的重任完全由编译器在编译阶段完成
    2. 当编译器解析你的代码时,它通过基类中虚函数的声明,完全了解每一个虚函数(如 vtable[0], vtable[1])应有的正确签名(返回类型、参数列表)
    3. 因此,当你写下 basePtr->virtualFunction()时,编译器生成的代码会:
      通过对象的vptr找到虚函数表
      根据函数在基类中的声明顺序(索引号)找到对应的函数地址
      生成一次函数调用,并基于它已知的、正确的函数签名来处理参数传递和返回值

RTTICompleteObjectLocator

  1. 概述
    1. 它是Microsoft Visual C++MSVC)编译器实现运行时类型识别(RTTI) 的核心数据结构,包含了在运行时进行类型识别(typeid)和安全的跨继承层次转换(dynamic_cast)所需的全部信息
  2. 成员
    1. signature
      DWORD
      一个魔数签名,用于验证结构的有效性。在32位程序中通常为0x00000000
    2. offset
      DWORD
      核心成员。表示当前虚函数表(vftable)指针距离完整对象起始地址的偏移量
      在简单单继承中,此值通常为0;在多重继承中,若当前vftable属于非首位的基类,则此值非零
    3. cdOffset
      DWORD
      构造位移偏移。用于在对象构造/析构过程中调整this指针,确保在非完整构造的对象上也能正确执行dynamic_cast
    4. pTypeDescriptor
      TypeDescriptor*
      指向描述具体类型的TypeDescriptor结构体的指针。该结构体包含了类型的名称(name())等核心信息,是typeid运算符的直接数据来源
    5. pClassDescriptor
      RTTIClassHierarchyDescriptor*
      指向描述类继承层次的RTTIClassHierarchyDescriptorCHD)结构体的指针
      这是实现dynamic_cast的关键,它描述了类的完整继承图谱

其他

共享内存
vector迭代器失效问题
std::move
进程间通信方式
进程间通信的效率
线程间同步方式
std::atomic
快速排序
堆排序
快速排序和分治算法
用最快的时间找到单链表的中间结点在main函数之前做事情
检测堆内存泄露的手段(内存泄露工具)
CPU占用高的原因以及处理
消费者生产者的同步问题

声明:本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2025-11-11
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享