【C++】内存管理

简介: 【C++】内存管理

前言:在前面很长一段时间我们都在学习类和对象这块地方,今天我们将进一步的学习内存管理,为后面将要学习的内容做铺垫。

d6dc0126edd141a985d72de501ef756b.jpg


内存管理

这里我们先来回顾一下前面学习C语言所了解内存分配的区域:

C/C++的内存分配主要分为以下几个区域:

  1. 栈(Stack):栈是由编译器自动分配和释放的内存区域,用于存储局部变量函数参数函数调用的上下文信息。栈的分配和释放都是自动的,遵循"后进先出"(LIFO)的原则。
  2. 堆(Heap):堆是由程序员手动分配和释放的内存区域,用于存储动态分配的对象。堆的内存分配和释放必须由程序员显式地调用newdeletemallocfree等函数来进行。
  3. 全局变量区(Global Data Area):全局变量区也称为静态数据区,用于存储全局变量和静态变量。全局变量在程序运行期间一直存在,直到程序结束才被释放。
  4. 常量区(Constant Data Area):常量区用于存储常量数据,如字符串字面量和常量全局变量。该区域的数据在程序运行期间不可修改。
  5. 代码区(Code Area):代码区存储程序的可执行代码,包括函数体和指令。该区域通常是只读

的。

需要注意的是,不同的编译器和操作系统可能对内存的管理方式有所不同。因此,在编写跨平台的C/C++程序时,应当遵循标准的内存分配和释放规则,避免依赖于特定编译器或操作系统的行为。


C语言的内存管理方式

动态分配是在程序运行时根据需要手动分配和释放的内存空间。动态分配使用malloc、calloc或realloc函数动态申请内存空间,并使用free函数释放已分配的内存空间。动态分配的内存可以在函数之间共享,并且可以灵活地调整大小。但需注意,在使用动态分配的内存之后需要手动释放,否则会导致内存泄漏。关于这部分不是今天的重点,因此如果有不懂的地方可以参考我之前的博客C语言动态内存管理。

C++的内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

newdelete操作符:new操作符用于在堆上分配内存,delete操作符用于释放分配的内存。

new操作符详解

  1. 开辟一块int类型的空间,让指针指向这块空间
int* buffer1 = new int;//new一个int类型的空间

2. 开辟一块int类型的空间并初始化为10,让指针指向这块空间

int* buffer2 = new int(10);// new一个int类型的空间并初始化为10

3. 开辟一块具有10个int类型的空间,让指针指向这块空间

int* buffer3 = new int[10];// new10个int类型的空间

  1. 开辟一块具有10个int类型的空间并且对其初始化(未初始化的部分自动初始化成0),让指针指向这块空间.
nt* buffer4 = new int[10]{ 10,9,8,7,6,5 }; //跟数组的初始化很像,大括号有几个,初始化几个,其余为0。不过C++11才支持的语法


delete操作符详解

delete buffer;  // 释放指针p所指向的内存空间

当使用new操作符分配了一个数组时,应使用delete[]操作符释放内存空间,例如:

int* arr = new int[10];  // 分配一个int类型的数组
// 使用arr
delete[] arr;  // 释放数组内存空间

new / delete 操作自定义类型

结论

申请空间时:malloc只开空间,new既开空间又调用构造函数初始化。

释放空间时:delete会调用析构函数,free不会.

实例演示:

class Myclass
{
public:
  Myclass()//默认构造
  {
    cout << "默认构造" << i <<endl;
    i++;
    
  }
  ~Myclass()//析构
  {
    cout << "析构函数" << x <<endl;
    x++;
  }
private:
  static int x;
  static int i;
};

int Myclass::x = 0;
int Myclass::i = 0;

int main()
{
  Myclass* p1 = new Myclass;
  delete p1;
  return 0;
}


实例演示:

class Myclass
{
public:
  Myclass()//默认构造
  {
    cout << "默认构造" << i <<endl;
    i++;
    
  }
  ~Myclass()//析构
  {
    cout << "析构函数" << x <<endl;
    x++;
  }
private:
  static int x;
  static int i;
};

int Myclass::x = 0;
int Myclass::i = 0;

int main()
{
  Myclass* p2 = new Myclass[10];
  delete[]p2;
  return 0;
}

总结:在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会,并且malloc如若开辟内存失败,会返回空指针这个我们都晓得的,但是new失败会抛异常

operator new与operator delete函数

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

"operate new"和"operate delete"是C++中的两个自定义内存管理函数。它们可以重载,用于自定义对象的内存分配和释放。

  1. 重载operator new函数:通过重载operator new函数,可以自定义对象在内存中的分配方式。其语法为:
void* operator new(size_t size);

operator new函数接受一个size_t类型的参数,表示要分配的内存大小,返回一个void类型的指针,指向分配的内存空间。可以在函数内部使用标准的内存分配函数(如malloc)或其他自定义的分配方式。

示例:

void* operator new(size_t size)
{
    void* p = malloc(size);  // 使用malloc函数分配内存
    if (!p) {
        throw std::bad_alloc();  // 内存分配失败,抛出异常
    }
    return p;
}
  1. 重载operator delete函数:通过重载operator delete函数,可以自定义对象的内存释放方式。其语法为:
void operator delete(void* ptr);


operator delete函数接受一个void类型的指针作为参数,表示要释放的内存空间。可以在函数内部使用标准的内存释放函数(如free)或其他自定义的释放方式。

示例:

void operator delete(void* ptr)
{
    free(ptr);  // 使用free函数释放内存
}

通过重载operator new和operator delete函数,可以实现对内存分配和释放的个性化控制。这在一些特殊情况下非常有用,例如实现内存池、内存统计等功能。需要注意的是,重载的operator new和operator delete函数必须在对应的类内使用static关键字进行声明。


好啦,今天的内容就到这里啦,下期内容预告STL与string,类和对象就在这里和大家告一段落了,各位加油呐!


结语:今天的内容就到这里吧,谢谢各位的观看,如果有讲的不好的地方也请各位多多指出,作者每一条评论都会读的,谢谢各位。


相关文章
|
19天前
|
存储 Java C++
C++ 引用和指针:内存地址、创建方法及应用解析
C++中的引用是现有变量的别名,创建时需用`&`运算符,如`string &meal = food;`。指针存储变量的内存地址,使用`*`创建,如`string* ptr = &food;`。引用必须初始化且不可为空,而指针可初始化为空。引用在函数参数传递和提高效率时有用,指针适用于动态内存分配和复杂数据结构操作。选择使用取决于具体需求。
38 9
|
23天前
|
存储 Linux C语言
【C++初阶】6. C&C++内存管理
【C++初阶】6. C&C++内存管理
34 2
|
2月前
|
存储 程序员 Linux
1024程序员节特辑 | C++入门指南:内存管理(建议收藏!!)
1024程序员节特辑 | C++入门指南:内存管理(建议收藏!!)
41 0
|
2月前
|
存储 监控 算法
【C++ 软件设计思路】高效管理历史任务记录:内存与磁盘结合的策略解析
【C++ 软件设计思路】高效管理历史任务记录:内存与磁盘结合的策略解析
58 0
|
7天前
|
存储 缓存 算法
C++从入门到精通:4.6性能优化——深入理解算法与内存优化
C++从入门到精通:4.6性能优化——深入理解算法与内存优化
|
7天前
|
存储 程序员 编译器
C++从入门到精通:3.4深入理解内存管理机制
C++从入门到精通:3.4深入理解内存管理机制
|
7天前
|
存储 人工智能 程序员
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
【重学C++】【内存】关于C++内存分区,你可能忽视的那些细节
37 1
|
7天前
|
C语言 C++
【C++基础(九)】C++内存管理--new一个对象出来
【C++基础(九)】C++内存管理--new一个对象出来
|
8天前
|
存储 编译器 Linux
c++的学习之路:8、内存管理与模板
c++的学习之路:8、内存管理与模板
9 0
|
14天前
|
存储 Linux C语言
C/C++之内存旋律:星辰大海的指挥家
C/C++之内存旋律:星辰大海的指挥家
23 0