在C/C++的面试时,对于new/delete和malloc/free这两对的使用和区别经常被考查到,如果这种基础的问题都答不上来,估计很难过面试了。这篇文章仅仅是浅显的讲一下,仅供参考。

一、new和delete

new和delete是C++的运算符,用于动态分配内存和释放内存。

new表达式

标准库定义了operator new函数的几个重载版本,没有使用noexcept说明的版本在内存分配失败时可能会抛出bad_alloc异常,而使用了的不会抛出异常。

void* operator new  ( size_t );
void* operator new[]( size_t );
void* operator new ( size_t , const nothrow_t& ) noexcept;
void* operator new[]( size_t , const nothrow_t& ) noexcept;

当我们使用new表达式时,实际执行了三步操作:

  • new表达式调用上面的operator new(或者operator new[])的标准库函数,函数分配一块足够大的、原始的、未命名的内存空间以便存储特定类型的对象(或者对象的数组)。
  • 编译器运行相应的构造函数以构造这些对象,并为其传入初始值。
  • 对象被分配了空间并构造完成,返回一个指向该对象的指针。

对于operator new函数或者operator new[]函数来说,它的返回类型必须是void*,第一个形参的类型必须是size_t且该形参不能含有默认实参。当编译器调用operator new或者operator new[]函数时,会把存储指定对象或者指定对象的数组所需的字节数传给size_t形参。

delete表达式

标准库也定义了operator delete函数的几个重载版本,noexcept说明符表示在内存分配失败时返回空指针而不是抛出bad_alloc异常。

void operator delete  ( void* ) noexcept;
void operator delete[]( void* ) noexcept;
void operator delete ( void* , const nothrow_t& ) noexcept;
void operator delete[]( void* , const nothrow_t& ) noexcept;

当我们使用delete表达式时,实际执行了两步操作:

  • 对指针所指的对象或者所指的数组中的元素执行对应的析构函数
  • 编译器调用operator delete(或者operator delete[])的标准库函数释放内存空间。

对于operator delete函数或者operator delete[]函数来说,它们的返回类型必须是void,第一个形参的类型必须是void*。执行一条delete表达式将调用相应的operator函数,并用指向待释放内存的指针来初始化void*形参。

二、malloc和free

malloc和free是C/C++中的标准库函数,也是用于申请动态内存和释放内存。

void* malloc( size_t size );
void free( void* ptr );

malloc函数接受一个表示待分配字节数的size_t,返回指向分配空间的指针;如果分配失败,则返回空指针。free函数接受一个void*,它是malloc返回的指针的副本,free将相关内存返还给系统。注意:malloc函数并不会调用构造函数来初始化内存,free函数也不会自动调用析构函数。

三、new和malloc、delete和free的区别


int *p1 = new int;     // 没有初始化列表, 所以没有初始化
int *p2 = new int();  // 空初始化列表, 执行zero初始化, 所以初始化为0
int *p3 = new int(3);  // 非空初始化列表, 执行值初始化, 所以初始化为3
// 注:对于没有构造函数的内置类型,new会不会初始化在于有没有初始列表(空列表“()”也算)
int *p4 = new int[100]; // 分配大小为sizeof(int)*100; int *p5 = (int*)malloc(sizeof(int)*128);
double *p6 = (double*)malloc(sizeof(double)*12);

new和malloc的区别:

  1. new是一个运算符,malloc()是一个库函数。

  2. new会调用构造函数,而malloc()不会。

  3. new返回指定类型的指针,而malloc()返回void*。

  4. new会自动计算需要分配的空间,而malloc()需要手工计算字节数。

  5. new可以被重载,而malloc()不能。

delete p1;
delete [] p2;
free(p3);
free(p4);

delete和free的区别:

  1. delete是一个运算符,free()是一个库函数。

  2. delete会调用析构函数,而free()不会。

  3. delete可以被重载,而free()不能。

总结:

malloc和free是C/C++中的标准库函数,new和delete是C++的运算符。对于非内置数据类型的对象而言,光用maloc/free 无法满足动态对象的要求。对象在创建的同时要自动执行构造函数, 对象消亡之前要自动执行析构函数。由于malloc/free 是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加malloc/free。

C++学习之new与delete、malloc与free的更多相关文章

  1. 深入C++ new/delete,malloc/free解析

    深入C++ new/delete,malloc/free解析 1.malloc与free是C++/C语言的标准库函数.new/delete是C++的运算符. 它们都可用于申请动态内存和释放内存 2.对 ...

  2. C++ new delete malloc free

    title: C++ new delete malloc free date: 2020-03-10 categories: c++ tags: 语法 C++的new delete malloc fr ...

  3. 内存分配(new/delete,malloc/free,allocator,内存池)

    以下来源http://www.cnblogs.com/JCSU/articles/1051826.html 程序员们经常编写内存管理程序,往往提心吊胆.如果不想触雷,唯一的解决办法就是发现所有潜伏的地 ...

  4. new和delete malloc和free

    程序中动态分配的对象存放在自由存储区(free store)或堆(heap). C语言程序使用一对标准库函数malloc和free在自由存储区中分配存储空间,而C++语言则使用new和delete表达 ...

  5. CUBRID学习笔记 45 REPLACE DELETE MERGE 教程

    c#,net,cubrid,教程,学习,笔记欢迎转载 ,转载时请保留作者信息.本文版权归本人所有,如有任何问题,请与我联系wang2650@sohu.com . 过错 ------ 官方文档是英文的, ...

  6. new,delete,malloc,free

    malloc/free是C语言中的内存申请和释放函数,利用它们可方便地管理内存.而在C++中我们又有了新的工具:new/delete.new/delete在管理内存的同时会调用类的构造函数和析构函数, ...

  7. 内存分配方式,堆区,栈区,new/delete/malloc/free

    1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建.在执行函数时 ...

  8. C++之new/delete/malloc/free详解

    主要内容: 1.  C语言中的函数malloc和free 2.  C++中的运算符new和delete 3.  new/delete与malloc/free之间的联系和区别 4.  C/C++程序的内 ...

  9. C++/C语言的标准库函数与运算符的区别new/delete malloc/free

    malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符.它们都可用于申请动态内存和释放内存.下面来看他们的区别. 一.操作对象有所不同 malloc与free是C++ ...

随机推荐

  1. C#常见问题总结(三)

    11.sql比access好在哪里,为什么都用sql 解决方法: 数据量大,可以在服务器端,access一般在单机的时候用 12.c#基础视频教程有吗 解决方法: 零基础学C#这本书带全套C#基础视频 ...

  2. python自动化--语言基础五面向对象、迭代器、range和切片的区分

    面向对象 一.面向对象简单介绍: class Test(): #类的定义 car = "buick" #类变量,定义在类里方法外,可被对象直接调用,具有全局效果 def __ini ...

  3. SQL SERVER 2008 在某表中新增一列时失败

    背景:新增列语句如:“alter table 表名 add 列名 float default 0 with values”(用VS2010做网站,这句话是在C#代码里执行的) 报错提示: 警告: 已经 ...

  4. Exceptions & Errors - 异常与错误

    来源于 Ry’s Objective-C Tutorial - RyPress 一个学习Objective-C基础知识的网站. 个人觉得很棒,所以决定抽时间把章节翻译一下. 本人的英语水平有限,有让大 ...

  5. std list/vector sort 自定义类的排序就是这么简单

    所以,自己研究了一下,如下:三种方式都可以,如重写<,()和写比较函数compare_index.但是要注意对象和对象指针的排序区别. 1.容器中是对象时,用操作符<或者比较函数,比较函数 ...

  6. CAD使用GetxDataDouble读数据(网页版)

    主要用到函数说明: MxDrawEntity::GetxDataDouble2 读取一个Double扩展数据,详细说明如下: 参数 说明 [in] LONG lItem 该值所在位置 [out, re ...

  7. JavaScipt30(第四个案例)(主要知识点:数组原型链上的一些方法)

    承接上文,下面是第四个案例 附上项目链接: https://github.com/wesbos/JavaScript30 const inventors = [ { first: 'Albert', ...

  8. HDU多校Round 1

    Solved:5 rank:172 A.Maximum Multiple #include <stdio.h> #include <algorithm> #include &l ...

  9. 用TWaver加载大型游戏场景一例

    游戏中经常会出现一些大型的户外场景,例如一个小镇.一座古城等.通常这种场景中包含了较多的建筑.道路.桥梁等等元素,其3D模型比较大且复杂.在使用TWaver加载时,可使用一些技巧,让加载速度更快.显示 ...

  10. unity问题笔记

    拖放在预制体中的图片等资源,他们的加载需要我们控制吗?我觉得不需要控制,但是如果按照现在的这种方式保存资源到非标准的resources文件下,那怎么加载?ulua的规则是这样查找资源的吗?猜想:客户端 ...