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. 野指针的问题也会导致空间找不回来系统收不回去

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

目录
相关文章
|
2月前
|
安全 C语言 C++
比较C++的内存分配与管理方式new/delete与C语言中的malloc/realloc/calloc/free。
在实用性方面,C++的内存管理方式提供了面向对象的特性,它是处理构造和析构、需要类型安全和异常处理的首选方案。而C语言的内存管理函数适用于简单的内存分配,例如分配原始内存块或复杂性较低的数据结构,没有构造和析构的要求。当从C迁移到C++,或在C++中使用C代码时,了解两种内存管理方式的差异非常重要。
123 26
|
7月前
|
存储 程序员 编译器
玩转C++内存管理:从新手到高手的必备指南
C++中的内存管理是编写高效、可靠程序的关键所在。C++不仅继承了C语言的内存管理方式,还增加了面向对象的内存分配机制,使得内存管理既有灵活性,也更加复杂。学习内存管理不仅有助于提升程序效率,还有助于理解计算机的工作原理和资源分配策略。
|
3月前
|
C语言 C++
c与c++的内存管理
再比如还有这样的分组: 这种分组是最正确的给出内存四个分区名字:栈区、堆区、全局区(俗话也叫静态变量区)、代码区(也叫代码段)(代码段又分很多种,比如常量区)当然也会看到别的定义如:两者都正确,记那个都选,我选择的是第一个。再比如还有这样的分组: 这种分组是最正确的答案分别是 C C C A A A A A D A B。
58 1
|
9月前
|
存储 缓存 编译器
【硬核】C++11并发:内存模型和原子类型
本文从C++11并发编程中的关键概念——内存模型与原子类型入手,结合详尽的代码示例,抽丝剥茧地介绍了如何实现无锁化并发的性能优化。
398 68
|
6月前
|
存储 Linux C语言
C++/C的内存管理
本文主要讲解C++/C中的程序区域划分与内存管理方式。首先介绍程序区域,包括栈(存储局部变量等,向下增长)、堆(动态内存分配,向上分配)、数据段(存储静态和全局变量)及代码段(存放可执行代码)。接着探讨C++内存管理,new/delete操作符相比C语言的malloc/free更强大,支持对象构造与析构。还深入解析了new/delete的实现原理、定位new表达式以及二者与malloc/free的区别。最后附上一句鸡汤激励大家行动缓解焦虑。
|
7月前
|
安全 C语言 C++
彻底摘明白 C++ 的动态内存分配原理
大家好,我是V哥。C++的动态内存分配允许程序在运行时请求和释放内存,主要通过`new`/`delete`(用于对象)及`malloc`/`calloc`/`realloc`/`free`(继承自C语言)实现。`new`分配并初始化对象内存,`delete`释放并调用析构函数;而`malloc`等函数仅处理裸内存,不涉及构造与析构。掌握这些可有效管理内存,避免泄漏和悬空指针问题。智能指针如`std::unique_ptr`和`std::shared_ptr`能自动管理内存,确保异常安全。关注威哥爱编程,了解更多全栈开发技巧。 先赞再看后评论,腰缠万贯财进门。
336 0
|
8月前
|
存储 程序员 编译器
什么是内存泄漏?C++中如何检测和解决?
大家好,我是V哥。内存泄露是编程中的常见问题,可能导致程序崩溃。特别是在金三银四跳槽季,面试官常问此问题。本文将探讨内存泄露的定义、危害、检测方法及解决策略,帮助你掌握这一关键知识点。通过学习如何正确管理内存、使用智能指针和RAII原则,避免内存泄露,提升代码健壮性。同时,了解常见的内存泄露场景,如忘记释放内存、异常处理不当等,确保在面试中不被秒杀。最后,预祝大家新的一年工作顺利,涨薪多多!关注威哥爱编程,一起成为更好的程序员。
315 0
|
7月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
3月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
88 0
|
3月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
166 0