深入理解C++中的new/delete和malloc/free动态内存管理及区别介绍

malloc/free和new/delete的区别

  • malloc/free是C/C++标准库的函数;new/delete是C++操作符。
  • malloc/free只是动态分配内存空间/释放空间;new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理资源。
  • malloc/free需要手动计算类型大小且返回值类型为void*;new/delete可自动计算类型的大小,返回对应类型的指针。
  • malloc/free管理内存失败会返回0;new/delete等的方式管理内存失败会抛出异常。

在C++ Primer书中有提到说: new/delete的表达式与标准库函数同名了,所以系统并没有重载new或delete表达式。new/delete真正的实现其实是依赖下面这几个内存管理接口的。

void *operator new(size_t); //allocate an object
void *operator delete(void *); //free an object

void *operator new[](size_t); //allocate an array
void *operator delete[](void *); //free an array

malloc/free和new/delete的底层实现

new的底层实现

// new.cpp
#include <cstdlib>
#include <new>

_C_LIB_DECL
int __cdecl _callnewh(size_t size) _THROW1(_STD bad_alloc);
_END_C_LIB_DECL

void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
 { // try to allocate size bytes
 void *p;
 while ((p = malloc(size)) == 0)
  if (_callnewh(size) == 0)
  { // report no memory
   _THROW_NCEE(_XSTD bad_alloc, );
  }

 return (p);
 }

delete的底层实现

#include <cruntime.h>
#include <malloc.h>
#include <new.h>
#include <windows.h>
#include <rtcsup.h>

void operator delete( void * p )
{
 RTCCALLBACK(_RTC_Free_hook, (p, 0));

 free( p );
}

new[]的底层实现

#include <new>

void *__CRTDECL operator new[](size_t count) _THROW1(std::bad_alloc)
	{	// try to allocate count bytes for an array
	return (operator new(count));
	}

delete[]的底层实现

#ifdef CRTDLL
#undef CRTDLL
#endif

#ifdef MRTDLL
#undef MRTDLL
#endif

#define _USE_ANSI_CPP // suppress defaultlib directive for Std C++ Lib
#include <new>

extern void __CRTDECL operator delete[](void *ptr) _THROW0();

void __CRTDECL operator delete[](void *ptr,
	const std::nothrow_t&) _THROW0()
	{	// free an allocated object
	operator delete[](ptr);
	}

malloc/free和new/delete的执行过程

new的执行过程

new(int size) --> operator new() --> malloc() --> constructor function --> return ptr

delete的执行过程

delete ptr --> destructor function --> operator delete() --> free

new[]的执行过程

new[count] --> operator new[]() --> operator new() --> malloc() --> constructor function --> return ptr

delete[]的执行过程

delete[] ptr --> destructor function --> operator delete[]() --> operator delete() --> free
  • 依次调用指针指向对象数组中每个对象的析构函数
  • 调用operator delete[]()operator delete[]()再调用operator delete
  • 底层用free执行operator delete表达式,依次释放内存
  • operator delete[]()数组的个数存放在指针的前4位

参考

https://www.jb51.net/article/161885.htm

总结

到此这篇关于深入理解C++中的new/delete和malloc/free动态内存管理的文章就介绍到这了,更多相关C++中的new/delete和malloc/free动态内存管理内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C/C++中的内存管理小结

    前言 我们最初熟知的内存开辟方式: int val = 20: 在栈空间上开辟4个字节 char array[10]: 在栈空间上开辟10个字节的连续空间 上述开辟空间的方式有两个特点: 空间开辟大小是固定的. 数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配. 但是对于空间的需求,不仅仅是上述的情况,有时候我们需要的空大小在程序运行时才能知道,那此时静态的开辟空间的方式就不能满足了,我们这时候只能试试动态内存开辟. 这篇博客就来带大家梳理一下C/C++中的内存管理. 一:C/C

  • 养成良好的C++编程习惯之内存管理的应用详解

    开篇导读    虽然本系列文章定位为科普读物,但本座相信它们不但适合新手们学习借鉴,同时也能引发老鸟们的反思与共鸣.欢迎大家提出宝贵的意见和反馈 ^_^ 在开篇讲述本章主要内容之前,本座首先用小小篇幅论述一下一种良好的工作习惯 -- 积累.提炼与求精.在工作和学习的过程中,不断把学到的知识通过有效的方式积累起来,形成自己的知识库,随着知识量的扩大,就会得到从量变到质变的提升.另外还要不断地对知识进行提炼,随着自己知识面的扩大以及水平的提升,你肯定会发现原有知识库存在着一些片面.局限.笨拙甚至错误

  • C++中new与delete、malloc与free应用分析

    一般来说,在C/C++的面试时,对于new/delete和malloc/free这两对的使用和区别经常被考查到,如果这种基础的问题都答不上来,估计很难过面试了.本文即是对new/delete和malloc/free这两对的使用和区别较为简单的分析一下,供大家参考. 一.new和delete new和delete是C++的运算符,用于动态分配内存和释放内存. 1.new表达式 标准库定义了operator new函数的几个重载版本,没有使用noexcept说明的版本在内存分配失败时可能会抛出bad

  • C++中malloc与free、new与delete的详解与应用

    C++面试经常会问到关于malloc/free和new/delete的区别,网上有不同版本的解释,这里总结下并加上个人理解和使用. 两者相同点 1.都可以申请动态堆内存. 两者不同点 1.new/delete是C++的操作符,malloc/free是C/C++的标准库函数. 2.new申请的可以理解为对象,new时会调用构造函数,返回指向该对象的指针,delete时调用析构函数:malloc申请的只是内存,不是对象. 3.new/delete是保留字,不需要头文件支持:malloc/free需要

  • 老生常谈C/C++内存管理

    内存分配方式 简介 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放.栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限. 堆:就是那些由 new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个 delete.如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收. 自由存储区:就是那些由mall

  • 深入理解C++中的new/delete和malloc/free动态内存管理及区别介绍

    malloc/free和new/delete的区别 malloc/free是C/C++标准库的函数:new/delete是C++操作符. malloc/free只是动态分配内存空间/释放空间:new/delete除了分配空间还会调用构造函数和析构函数进行初始化与清理资源. malloc/free需要手动计算类型大小且返回值类型为void*:new/delete可自动计算类型的大小,返回对应类型的指针. malloc/free管理内存失败会返回0:new/delete等的方式管理内存失败会抛出异常

  • c++动态内存管理详解(new/delete)

    目录 前言 用法上 对内置类型 对自定义类型 new/delete底层原理 重载类的专属operatornew和operatordelete 定位new new/delete与malloc/free区别总结 内存泄漏 总结 前言 想必大家对c语言的动态内存分配并不陌生,忘了的小伙伴也可以看看我的这篇文章C语言动态内存分配 c语言的动态内存分配由于有些地方用起来比较麻烦同时检查错误的机制不适合c++,因此c++引入new/delete操作符进行内存管理,下面我们来深入探讨c++为什么要引入new/

  • 一文详解C++中动态内存管理

    目录 前言 1.C/C++程序的内存开辟 2.C语言中动态内存管理方式:malloc/calloc/realloc/free 2.1malloc.calloc.realloc区别? 3.C++内存管理方式 3.1 new/delete操作内置类型 3.2 new和delete操作自定义类型 3.3new和malloc处理失败 4.operator new与operator delete函数 4.1 operator new与operator delete函数 4.1.1 我们看看operator

  • C语言中动态内存管理图文详解

    目录 1.动态内存开辟的原因 2.动态内存函数的介绍 2.1malloc和free 2.2calloc 2.3realloc 3.常见的动态内存错误 3.1对NULL指针的解引用操作 3.2对动态开辟空间的越界访问 3.3对非动态开辟内存使用free 3.4使用释放一块动态开辟内存的一部分 3.5对同一块动态内存多次释放 3.6动态开辟内存忘记释放(内存泄漏) 4.练习 4.1练习1 4.1练习2 4.3练习3 4.4练习4 5.C/C++程序的内存开辟 总结 1.动态内存开辟的原因 常见的内存

  • 详解C语言中动态内存管理及柔性数组的使用

    目录 一.malloc 二.free 三.calloc 四.realloc 1.realloc在扩容时的情况 2.realloc也能实现malloc功能 五.使用动态内存的常见错误 1.free空指针 2.对动态开辟的空间越界访问 3.对非动态开辟内容free 4.只free动态开辟空间的一部分 5.对同一块内存多次free 6.动态内存空间忘记释放(内存泄漏) 六.柔性数组 1.柔性数组的概念 2.柔性数组的特点 3.柔性数组的使用场景 4.柔性数组的优点 一.malloc 这个函数向堆区申请

  • 详解C语言中的动态内存管理

    目录 一.动态内存管理 1.1为什么要有动态内存管理 1.2动态内存介绍 1.3常见的动态内存错误 一.动态内存管理 1.1为什么要有动态内存管理 1.1.1  在c语言中我们普通的内存开辟是直接在栈上进行开辟的 int i = 20;//在栈空间上开辟四个字节 int arr[10]={0}; //在栈中连续开辟四十个字节 这样开辟的特点是: (1)他所开辟的空间是固定的 (2)数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配 但对于空间的需求,我们有的时候并不知道,有可能空间

  • 一文带你了解C语言中的动态内存管理函数

    目录 1.什么是动态内存管理 2.为什么要有动态内存管理 3.如何进行动态内存管理 3.1 malloc 3.2 free 3.3 calloc 3.4 realloc 总结 1.什么是动态内存管理 平时我们写代码,一种非常常见的写法是: int a = 0; // 创建一个变量 int arr[10] = {0}; // 创建一个数组 当你创建变量a的时候,其实是向内存中申请了4个字节的空间来存放一个整数.而当你创建数组arr的时候,是向内存中申请了40个字节的空间来存放10个整数.当你这么写

  • 实例理解SQL中truncate和delete的区别

    本文以一个简单实例为大家介绍了SQL中truncate和delete的区别,帮助大家理解,具体内容如下 ---创建表Table1 IF OBJECT_ID('Table1','U') IS NOT NULL DROP TABLE Table1 GO CREATE TABLE Table1 (ID INT NOT NULL, FOID INT NOT NULL) GO --插入测试数据 INSERT INTO Table1 VALUES(1,101),(2,102),(3,103),(4,104)

  • Go语言中结构体方法副本传参与指针传参的区别介绍

    GO语言结构体方法跟结构体指针方法的区别 首先,我定了三个接口.一个结构和三个方法: type DeptModeA interface { Name() string SetName(name string) } type DeptModeB interface { Relocate(building string, floor uint8) } type Dept struct { name string building string floor uint8 Key string } fun

随机推荐