C++的内存分布及内存管理

简介: C++的内存分布及内存管理

对于C语言和C++而言,它们的内存分布都是一样的

而内存是编写程序时必须要关心的点,一定要防止内存过载 内存泄漏等问题

一旦内存出现问题程序就会直接崩溃,甚至严重的还会导致系统死机等

C/C++的内存分布

C/C++的内存分布可以简易的划分为以下图示


7eabe771d5ed8f66cc26b6ec099a9c4c.png

不同的数据会存放在对应的空间中

  1. 栈又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的
  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库
  3. 堆存放动态开辟的内存分配,堆是可以上增长的。
  4. 数据段–存储全局数据和静态数据
  5. 代码段–可执行的代码/只读常量

C++的动态内存管理

对于C语言想要开辟一块内存可以用到 malloc、calloc、realloc这三个函数,而对于C++也有自己的开辟内存方式-- new负责开辟空间 delete负责释放空间。前者是C语言中的函数,而后者是C++中的操作符

new、delete的使用

int main() {
  //开辟一块int类型的空间并初始化为10
  int* a = new int(10);
  //开辟一块char类型的空间
  int* b = new int;
  //开辟一块连续的有10个double类型的空间
  double* c = new double[10];
  //如果申请的空间只有一个时
  delete a;
  a = nullptr;
  delete b;
  b = nullptr;
  //申请了连续空间时
  delete[] c;
  c = nullptr;
  return 0;
}

new/delete和malloc/free使用上的区别

  1. malloc申请出来的空间不可以进行初始化,但new可以
  2. malloc的返回值为void* 因此需要强转为指定类型,而new不需要
  3. malloc开辟空间时需要计算出空间的字节大小,而new不用它会自动识别类型只需要在[]里输入个数即可
  4. malloc开辟失败会返回NULL,new会捕捉异常
  5. 申请自定义类型空间时,malloc/free不会调用构造和析构函数,new会调用构造函数并且在delete释放空间前会调用析构函数清理资源

new和delete的底层原理

其实这两个的底层也是用malloc和free实现的,在C++中有两个全局函数 operator new、operator delete。这两个全局函数使用malloc和free定义的。在用户调用new和delete,它们会分别调用这两个全局函数。

new调用operator new函数申请空间,并执行对应类型的构造函数完成对象的初始化

delete首先会执行对应类型的析构函数,然后再调用operator delete释放空间

new T[N] 这种连续的开辟空间实际上会调用N次构造函数

delete[] 也就是会调用N次析构函数,不需要指明N

了解内存泄漏

内存泄漏是一种经常会出现的情况,如果是长期运行的程序出现了内存泄漏就会慢慢的导致系统卡死。

内存泄露可能出现的情况:

  1. 堆内存泄露也就是当用户开辟了空间后没有释放掉,那这部分空间就会一直无法被操作系统收回也就无法再次使用,长期积累就会导致内存空间不足
  2. 野指针的问题也会导致空间找不回来系统收不回去

因此在写程序时一定要额外的注意内存问题,只要有开辟了空间就一定要记得使用完之后释放。

目录
相关文章
|
14天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
36 6
|
14天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
38 4
|
1月前
|
存储 程序员 编译器
简述 C、C++程序编译的内存分配情况
在C和C++程序编译过程中,内存被划分为几个区域进行分配:代码区存储常量和执行指令;全局/静态变量区存放全局变量及静态变量;栈区管理函数参数、局部变量等;堆区则用于动态分配内存,由程序员控制释放,共同支撑着程序运行时的数据存储与处理需求。
112 21
|
1月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
1月前
|
存储 C语言 C++
【C++打怪之路Lv6】-- 内存管理
【C++打怪之路Lv6】-- 内存管理
41 0
【C++打怪之路Lv6】-- 内存管理
|
1月前
|
C++
C/C++内存管理(下)
C/C++内存管理(下)
50 0
|
1月前
|
存储 Linux C语言
C/C++内存管理(上)
C/C++内存管理(上)
38 0
|
1月前
|
Linux C++
Linux c/c++文件虚拟内存映射
这篇文章介绍了在Linux环境下,如何使用虚拟内存映射技术来提高文件读写的速度,并通过C/C++代码示例展示了文件映射的整个流程。
49 0
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
381 0
|
28天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
59 1