C++:C++内存管理

C++ 内存分区

C++ 内存分为 5 个主要区域:

栈 (Stack):存储局部变量、函数参数和返回地址。由编译器自动分配和释放,效率高但空间有限。

堆 (Heap):动态分配的内存区域,需手动管理(new/delete 或 malloc/free)。空间较大但容易产生碎片。

全局 / 静态存储区:存储全局变量和静态变量,程序启动时分配,结束时释放。

常量存储区:存储常量值(如字符串字面量),通常不可修改。

代码区:存储程序的机器码,只读区域。

堆和栈的区别

内存泄漏

定义:动态分配的内存未被正确释放,导致无法被再次使用。

产生原因:

忘记调用 delete/free

异常导致流程跳过释放代码

指针丢失(如被覆盖或作用域结束)

避免方法:

使用智能指针(如std::unique_ptr, std::shared_ptr)

RAII(资源获取即初始化)原则

统一内存管理接口(如封装 new/delete)

使用内存检测工具(如 Valgrind)

遵循 "谁分配,谁释放" 原则

智能指针

定义:自动管理对象生命周期的类模板,避免手动内存管理。

种类:

std::unique_ptr:独占所有权,不可复制但可移动。

std::shared_ptr:共享所有权,使用引用计数管理生命周期。

std::weak_ptr:弱引用,不增加引用计数,用于解决循环引用问题

cpp 复制代码
#include <memory>

void smart_ptr_example() {
    // unique_ptr
    std::unique_ptr<int> uptr = std::make_unique<int>(42);
    
    // shared_ptr
    std::shared_ptr<int> sptr1 = std::make_shared<int>(100);
    std::shared_ptr<int> sptr2 = sptr1;  // 引用计数+1
    
    // weak_ptr
    std::weak_ptr<int> wptr = sptr1;
    if (auto locked = wptr.lock()) {  // 检查对象是否存在
        // 使用locked
    }
} // uptr、sptr1/sptr2自动释放内存

new 和 malloc 的区别

delete 和 free 的区别

野指针

定义:指向已释放内存或未初始化内存的指针。

产生原因:

对象被 delete 后未置空指针

指针超出作用域后继续使用

使用未初始化的指针

避免方法:

delete 后立即将指针置为 nullptr

使用智能指针替代原始指针

遵循 "定义即初始化" 原则

避免返回局部对象的指针或引用

野指针和悬浮指针的区别

野指针:指向无效内存(如已释放的内存)。

悬浮指针:对象被销毁但引用 / 指针仍存在(通常由对象生命周期管理不当导致)。

内存对齐

定义:数据在内存中按特定字节边界对齐,以提高访问效率。

为什么需要:

硬件限制:部分架构只能访问对齐的内存地址。

性能优化:对齐的数据访问更快(减少内存访问次数)。

平台兼容性:确保代码在不同架构上行为一致。

cpp 复制代码
struct Example {
    char c;      // 1字节
    int i;       // 4字节(通常按4字节对齐)
    short s;     // 2字节(通常按2字节对齐)
};  // 总大小通常为12字节(非紧凑布局)

// 使用#pragma pack调整对齐
#pragma pack(1)
struct PackedExample {
    char c;      // 1字节
    int i;       // 4字节
    short s;     // 2字节
};  // 总大小为7字节(紧凑布局)
#pragma pack()

注意事项:

合理设计结构体成员顺序以减少填充

使用alignas关键字指定对齐方式

序列化时需考虑对齐对数据布局的影响

相关推荐
code_pgf14 分钟前
C++11 / C++14 / C++17 / C++20 新特性总结
c++·c++20
魔力女仆39 分钟前
分享一个 JS 鼠标跟随贪吃蛇背景库
开发语言·javascript·计算机外设
2401_894915531 小时前
GEO 搜索优化完整源码从零部署:环境配置、集群搭建全流程
开发语言·python·tcp/ip·算法·unity
麻瓜老宋2 小时前
AI开发C语言应用按步走,表达式计算器calc的第二十二步,分号赋值链式修复、TOKEN_ASSIGN
c语言·开发语言·atomcode
颜x小4 小时前
[C#] C++与c#语法对比
开发语言·c++·c#
weixin_423652134 小时前
C#使用JObject
开发语言·c#
国科安芯4 小时前
FreeRTOS RISC-V 浮点上下文切换移植:在 IAR 工程中完整保存 FPU 寄存器
java·开发语言·单片机·嵌入式硬件·算法·系统架构·risc-v
汉克老师5 小时前
GESP2026年3月认证C++八级( 第三部分编程题(2、子图最短路)精讲
c++·最短路·floyd·gesp8级
霸道流氓气质6 小时前
Java中集成Smile 技术教程:从入门到工程实践
java·开发语言
BerrySen1786 小时前
迈向 Next-Gen Java:企业级高并发架构演进与大模型 Agent 落地深度实战
java·开发语言·架构