欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【C++深度解析】40、new和malloc的区别

程序员文章站 2024-03-21 16:19:04
...

1 new 和 malloc 的区别

1、属性
new/delete 是 C++ 关键字。malloc/free 是库函数。

2、参数
new 以具体的类型为单位进行内存分配。malloc 需要显式地指出所需内存的字节数。

3、返回类型
new 操作符内存分配成功时,返回的是对象类型的指针,无须进行类型转换。
malloc 函数成功,返回 void* ,需要通过强制类型转换成我们需要的类型。

4、分配失败
new 内存分配失败时,会抛出 bac_alloc 异常。malloc 分配内存失败时返回NULL。

5、构造析构函数
new 能够触发构造函数的调用,在申请空间时可进行初始化。delete 先调用析构函数,先销毁对象再释放内存空间。

malloc 仅分配需要的内存空间,free 仅归还分配的内存空间。无法完成类对象构造和析构工作,不适合面向对象开发。

6、重载
C++ 允许重载 new/delete 操作符,malloc 不允许重载。

7、内存区域
new 操作符从*存储区上为对象动态分配内存空间,而 malloc 函数从堆上动态分配内存。*存储区是 C++ 基于 new 操作符的一个抽象概念,凡是通过 new 操作符进行内存申请,该内存即为*存储区。而堆是操作系统所维护的一块特殊内存。*存储区不等于堆,new 申请的对象就可以不位于堆中。

如果你在函数上面定义了一个指针变量,然后在这个函数里申请了一块内存让指针指向它。实际上,这个指针的地址在栈上,但是它所指向的内容却是在堆上面的!

编程实验:new 和 malloc 的区别

// 40-1.cpp
#include<iostream>
using namespace std;
class Test
{
    int* mp;
public:
    Test()
    {
        cout << "Test::Test()" << endl;
        mp = new int(100);
        cout << *mp << endl;
    }
    ~Test()
    {
        delete mp;
        cout << "Test::~Test()" << endl;
    }
};
int main()
{
    Test* pn = new Test;
    Test* pm = (Test*)malloc(sizeof(Test));
    delete pn;
    free(pm);
    return 0;
}
  • new 触发构造函数,先申请空间再初始化。delete 先调用析构函数,先销毁对象再释放内存空间。
  • malloc 仅分配内存,free 仅归还分配的内存空间。无法完成类对象构造和析构工作。
  • 所以第 22 行会调用构造函数,24 行调用析构函数。23,25行不会调用构造析构函数

编译运行

$ g++ 40-1.cpp -o 40-1
$ ./40-1
Test::Test()
100
Test::~Test()

2 new/delete 和 malloc/free 混用

如果我们将他们混用了会怎么样呢

2.1 new 申请 free 释放–内存泄漏

如果将上面代码第 24 行改为 free(pn); 也就是 new 申请的空间 free 释放,会造成内存泄漏,构造函数中申请了空间,free 不会触发析构函数,不会释放构造函数释放的空间,导致内存泄漏。没有摧毁对象,仅仅是释放了空间。

编译运行,可以看到没有调用析构函数。

$ g++ 40-1.cpp -o 40-1
$ ./40-1
Test::Test()
100

2.2 malloc 申请 delete 释放–摧毁不存在的对象

如果将上面代码第 25 行改为 delete pm; delete 会调用析构函数,malloc 并没有调用构造函数创建对象,这里却调用了析构函数,这可能会出问题。

编译运行,这里没有报错,但是析构函数释放资源可能带来深远的影响,千万别这么使用。

$ g++ 40-1.cpp -o 40-1
$ ./40-1
Test::Test()
100
Test::~Test()
Test::~Test()

所以: new 申请空间要用 delete 释放,malloc申请资源要 free 释放

3 小结

1、new 会触发构造函数,delete 会触发析构函数
2、malloc/free 不适合面向对象开发

相关标签: C++深度解析