欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > C/C++内存管理

C/C++内存管理

2025/6/19 9:12:22 来源:https://blog.csdn.net/m0_75187686/article/details/147530033  浏览:    关键词:C/C++内存管理

C/C++内存分布详解

C/C++ 中的内存分布后可以大致分为以下几部分:

1. 代码区 (Text Segment)

  • 存放程序代码,通常是只读区域,无法写入
  • 如果试图写入,会导致系统错误(如切换重启、核心崩溃)

2. 全局和静态区 (Data Segment)

  • 存放全局变量和 static 变量
  • 包括两部分:
    • 初始化区:已给初始值的变量
    • BSS(未初始化)区:未给值的全局或 static 变量
  • 系统在运行期初始化时为 BSS 区设置为 0

3. 堆区 (Heap)

  • 动态分配的内存,待用户手动释放
  • 从低地址向上增长,不同于栈(从高地址向下)
  • 如果释放后未当地处理,就会造成内存泄漏

4. 栈区 (Stack)

  • 函数调用时会分配栈字段,释放由系统管理
  • 常用于局部变量、函数参数、微临时内存
  • 从高地址向低分配,和堆区在地址上是对向增长,方便加载后续内存

5. 常量区 / 只读区 (Readonly Data)

  • 存放不可修改的常量、字符串定值
  • 如果尝试修改这些区,会引发系统错误

C语言中的动态内存管理

1. malloc / calloc / realloc

  • malloc(size_t size):分配 size 字节,内容未初始化
  • calloc(size_t n, size_t size):分配 n*size 字节,并处为 0
  • realloc(void* ptr, size_t size):重新分配内容,并保留旧数据

2. free

  • free(void* ptr) 用于释放堆内存,很重要!
  • 一旦释放后继续使用,就是释放后访问(Dangling Pointer)

3. 内存泄漏

  • 如果 malloc 后未 free,或 realloc 异常丢失原指针,都可能导致泄漏

4. 指针安全

  • malloc 分配后需要检查是否为 NULL

C++ 中的动态内存管理

1. new / delete

int* p = new int(10);   // 分配 4 字节,初始化为 10
int* arr = new int[10]; // 分配 40 字节,未初始化delete p;               // 释放单个对象
delete[] arr;           // 释放数组

2. 特性

  • new 调用 operator new,然后调用构造函数
  • delete 调用析构函数,然后调用 operator delete

3. 和 malloc/free 对比

方式分配内容实际调用是否调用构造/析构
malloc只分配空间malloc
new分配 + 构造operator new
delete析构 + 释放operator delete
free只释放free

operator new 与 operator delete

1. 原型

void* operator new(std::size_t size);
void operator delete(void* ptr);

2. 重写用法

class MyClass {
public:void* operator new(size_t size) {std::cout << "custom new\n";return ::operator new(size);}void operator delete(void* ptr) {std::cout << "custom delete\n";::operator delete(ptr);}
};

3. 应用场景

  • 自定义内存模型(内存混合、自定义分配器)
  • 辅助跟踪内存分配释放

new/delete 实现原理

1. new

  • 约翰:
T* p = new T(args);

实际等价于:

void* raw = operator new(sizeof(T));
T* p = new(raw) T(args);  // 应用 placement-new

2. delete

约翰:

delete p;

实际等价于:

p->~T();
operator delete(p);

定位型 new 表达式 (placement-new)

1. 格式

#include <new>
char buffer[sizeof(MyClass)];
MyClass* obj = new (buffer) MyClass(123);

2. 特点

  • 指定地址分配
  • 不分配新内存,而是在 buffer 中直接构造对象
  • 用户需要确保 buffer 夠大,并手动析构:
obj->~MyClass();

3. 应用场景

  • 内存混合(memory pool)
  • 水平集成(arena allocation)
  • 微控制内存分配等

结论

  • 熟悉内存分区帮助理解指针、内存泄漏、函数调用机制
  • 接触 C++ operator new / delete 能帮助我们编写高性能内存模型
  • placement-new 是较高级的技术,但对性能怪兽等有符合性应用

如果需要给出相关分区图视化或其他扩展,我可以继续添加简洁图视化图。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词