IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> new、delete与malloc、free的区别,内在实现。 -> 正文阅读

[C++知识库]new、delete与malloc、free的区别,内在实现。

首先明确,new、delete是C++里的运算符,和加减乘除一个类别;而malloc、free是C中的函数。

1、new 与 malloc的区别

????????执行内容

????????malloc,是按字节来分配内存的(意思是分配的大小,由自己指定),返回类型是void* ,因此在使用的时候,需要强制转换类型

????????new,是先开辟内存(由编译器根据你的对象类型,来决定开辟内存的大小),然后对内存进行初始化(执行构造函数),返回正确指向数据的指针。

????????返回类型

????????malloc,返回的是void* 的指针,如果申请内存失败,返回nullptr指针;

????????new,返回的是申请对象的指针,如果申请内存失败,抛出 bad_alloc类型的异常;因此两者判断是否开辟成功的所做也不一样。

int main()
{
    int *p = (int*)malloc(sizeof(int));
    if(p == nullptr) {
        return 0;
    }
       .....
    free(p);//为了避免野指针的存在,使用完之后给p赋值为nullptr;


    int* p = new(int(10))
    //if (p == nullptr) 这样判断是错误的
    
    try {
        int* p = new(int(10));
        delete p;//为了避免野指针的存在,使用完之后给p赋值为nullptr;
    }catch (bad_alloc){
        }

    return 0;
}

根据上面两个的分析,然后就可以自己来判断 new,malloc 的其他区别,下面可以自行分析?

2、delete 与 free的区别

? ? ? ? 执行过程

? ? ? ? delete:先调用析构函数,然后释放内存; free 只释放内存

????????根据delete的工作步骤,如果是针对于内置数据类型,例如 int,float等,new并不需要执行构造函数;delete并不需要执行析构函数,因此和malloc,free此时并没有什么区别。

3、new 内在实现

????????使用关键字 new 在堆上动态创建一个对象A时,A* p = new A() ,它实际上做了三件事:

????????1.向堆上申请一块内存空间(编译器生成)( operator new )

????????2.调用构造函数 (调用A的构造函数(如果A有的话))( placement new)

????????3.返回正确的指针,即申请数据类型的指针,A*。

????????operator new 和operator new[]功能都是仅仅分配内存,底层调用了 malloc 函数。 operator new是给new用的,operator new[]是给new[]用的。而且可以被重载。

void* operator new(size_t size) {
	void* p = malloc(size);
	if (p == nullptr) {
		throw bad_alloc();
	}
	return p;
}

void* operator new[](size_t size) {
	void* p = malloc(size);
	if (p == nullptr) {
		throw bad_alloc();
	}
	return p;
}

4、delete 内在实现

????????使用 delete 的时候,也是一样的,其行为如下:

????????1、定位到指针p所指向的内存空间,然后根据其类型,调用其自带的析构函数(内置类型不用)

????????2、然后释放其内存空间(调用 operator delete ,将这块内存空间标志为可用,然后还给操作系统)

? ? ? ? 3、在vs上测试,编译器并没有将申请的指针指向nullptr,因此此时指针为野指针,需要自己手动赋值为nullptr。

void operator delete[](void* ptr) {
	free(ptr);
}

void operator delete(void *ptr) {
	free(ptr);
}

5、何时需要配套使用

1、可以不配套

????????原则上都需要配套使用,但是当 new 的对象是基本数据类型,没有构造函数、析构函数时候,new 和 delete的实现和 malloc、free并没有什么区别,不配套使用,也不会报错。

int main()
{
    int* p = new int(10);
    delete[] p;
       
    int* p = new int[10];
    delete p;

    return 0;
}

2、必须配套

? ? ? ? 当存在构造函数和析构函数时候,必须配套使用。

class Test{
public:
    Test(int data = 10) : mdata(data) {}
    ~Test(){}
private:
    int mdata;
}


Test* ptr = new Test[5];
delete[] ptr;

????????当编译器开辟内存的时候,看见是要开辟的对象的数组,开辟的内存不只只是5*4个字节,还会在多加4个字节,表示一共有多少个对象。因此,在delete[] 的时候,编译器才知道要对几个对象进行析构。

? ? ? ?

Test* ptr = new Test();
delete[] ptr;

????????如果像上面这样操作的话,在delete[] ptr的时候,编译器看见 [], 就会像上找四个字节,此时的地址就不再是对象的地址了,因此产生错误。

Test* ptr = new Test[5];
delete ptr;//只会执行一次析构函数

????????同样道理,new[] delete也是,delete只会执行一次,只delete掉了ptr指向的那一个,后面的没法执行。

6、析构函数里要不要写delete

class A{
public:
    A(int data) : mdata(data){}
    ~A(){};
private:
    int data;
};

//~A(){  cout << "析构" << endl;    }


class A1{
public:
    A(int data) : mptr(new int[10]) {}
    ~A() {
        delete[] mptr;
    }
private:
    int* mptr;
};
    

?对象A析构函数,不需要写 delete,因为此时并没有在其他地方再次开辟内存;

对象A1析构函数,需要继续写 delete(同时注意配套),因此此时,在对象A1中,还存在在其他地方继续开辟内存,所以delete的时候,要把都清理干净。(嵌套delete)

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-08 22:10:02  更:2022-03-08 22:13:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:29:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码