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

 博主CSDN主页:卫卫卫的个人主页   专栏分类:高质量C++学习  代码仓库:卫卫周大胖的学习日记 关注博主和博主一起学习!一起努力!

目录标题

内存管理C/C++的内存分配主要分为以下几个区域:C语言的内存管理方式C++的内存管理方式new操作符详解delete操作符详解

new / delete 操作自定义类型operator new与operator delete函数

内存管理

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

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

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

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

C语言的内存管理方式

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

C++的内存管理方式

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

new操作符详解

开辟一块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类型的空间

开辟一块具有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 <

i++;

}

~Myclass()//析构

{

cout << "析构函数" << x <

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 <

i++;

}

~Myclass()//析构

{

cout << "析构函数" << x <

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++中的两个自定义内存管理函数。它们可以重载,用于自定义对象的内存分配和释放。

重载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;

}

重载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,类和对象就在这里和大家告一段落了,各位加油呐!

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

️

这里祝各位新年快乐 

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: