熟悉c++的朋友应该都知道,c++提供给了程序员与硬件打交道的可能性,比如说内存管理。一个高水平的c++程序员可以将c++程序的性能优化到极致,榨干硬件资源。而现在我想说说与内存管理有关的new 和 malloc()。

  先说说malloc(),malloc是从C语言那里继承过来的一个函数,其用于分配一片内存,它的返回结果是一个指向你所需求的内存的指针,其函数原型和使用例子如下:

/*
  函数原型
  其中__size是你要分配的大小,其单位是byte
*/
void* malloc(size_t __size); // 用例
int* pInt = (int*) malloc(sizeof(int));               // 分配了一个int
double* pDoubleArray = (double*) malloc(sizeof(double) * 5);   // 分配了一个double数组,其大小为5

  一般来说,malloc总是能为你分配出内存。但是也存在山穷水尽,内存不够用的情况。这时候malloc会返回一个空指针(NULL, nullptr)。当你使用malloc的时候,你最好每次都要判断一下返回的指针是否为空。

  现在内存已经分配出来了。当程序运行到某一些时刻,我又不想要这些内存了。这时候我们就要手动释放内存,否则的话就会造成内存泄露。通过free() 函数来释放内存,其函数原型和使用例子如下:

// 原型
void free(void* __ptr); // 用例
free(pInt);
free(pDoubleArray);

  有趣的是你传给free函数的只是一个指针,然而不管你是分配了一个元素还是分配了一个数组,free总能帮你释放掉这些内存(free 怎么知道你分配的数组的大小?)

  让我来详细的说说malloc在分配内存的时候干了什么。malloc在分配内存的时候,不仅仅会分配你需要的内存大小,它还会在你的内存的头部和尾部加上一些额外的信息(俗称cookie)。比如说用来DEBUG的信息和你的内存的大小。这就解释了为什么能free掉你的内存,因为它知道你这块内存是多大的。值得一提的是这些Cookie会占用一些内存。。。

  好了,malloc已经介绍的差不多了。还想说的一点是malloc只是一个第三方的函数,并不是操作系统的内核函数。如果有额外的需求的话,你可以设计自己的malloc。接下来谈谈new。

  new是c++提供的一个操纵符(或者说关键字)。其也是用于分配内存的。其用例如下:

int* pInt = new int(3);            // 分配并构造一个int
double* pDoubleArray = new double[5];    // 分配了一个double数组,其大小是5 delete pInt;                   // 删除单元素
delete[] pDoubleArray;             // 删除数组

  还是老话题,一般来说程序是能为你分配出内存的,但是实在山穷水尽了怎么办?这时候程序就会抛出一个std::bad_alloc异常。注意,这是new 和 malloc 的区别之一。但是难能可贵的是C++提供了一个机制来处理bad_alloc异常,其做法如下:

void BadAllocateHandler()
{
  std::cout << "啊,内存分配失败了" << std::endl;
  exit(0);
} std::set_new_handler(BadAllocateHandler);

  BadAllocateHandler是程序员自己写的当分配失败时的处理函数。而set_new_handler是c++提供的机制。一般来说当山穷水尽的时候你所应该做的事只有两件。要么让程序退出,要么想办法从别的地方挖一些内存来继续分配。

  你已经知道了new是一个关键字。对于一个程序来说,一切的动作都将回到函数调用。所以new的时候到底发生了什么呢?当你new的时候,首先程序会去调用::operator new()这个函数。然后::operator new()中程序会去调用malloc()。 喔!一切都明了了,原来new的本质也是去调用malloc函数!!同理,delete的本质是去调用free()函数。

  虽然new的本质是去调用malloc,但是new 和 malloc还有一点很大的不同。那就是new 出来内存后,new会帮你把对象给构造出来,而malloc只是分配内存。具体例子如下:

class MyObj {
public:
  public MyObj(int value) : val(value) {}
  int val;
}; MyObj* obj = new MyObj(4);
MyObj* obj1 = (MyObj*) malloc(sizeof(MyObj));

  new 的做法是在malloc分配出内存后,编译器会直接调用类的构造函数在这片内存中构造出对象。注意!只有编译器能直接调用类的构造函数。而你使用malloc的话,是无法直接在上面构造出对象的。

  好了。new和malloc说的差不多了,接下来要说说内存管理以及内存池相关的知识,详情参见另一篇博文。

说说new 和 malloc()的更多相关文章

  1. malloc 与 free函数详解<转载>

    malloc和free函数详解   本文介绍malloc和free函数的内容. 在C中,对内存的管理是相当重要.下面开始介绍这两个函数: 一.malloc()和free()的基本概念以及基本用法: 1 ...

  2. C 语言中 malloc、calloc、realloc 和free 函数的使用方法

    C标准函数库中,常见的堆上内存管理函数有malloc(), calloc(), recalloc(), free(). 之所以使用堆,是因为栈只能用来保存临时变量.局部变量和函数参数.在函数返回时,自 ...

  3. 以冒泡排序为例--malloc/free 重定向stdin stdout

    esort.c 代码如下,可关注下mallloc/free,freopen重定向的用法,排序为每轮将最小的数放在最前面: #include<stdio.h> #include<mal ...

  4. 内存动态分配之realloc(),malloc(),calloc()与new运算符

    1,malloc与free是C/C++的标准库函数,new/delete是C++的运算符,是C++面向对象的特征,它们都可用于申请动态内存和释放内存.2,对于非内部数据类型的对象而言,光用maloc/ ...

  5. 在dll里malloc/new/cvCreate分配内存,在exe里free/Releases释放内存时会出错。

    写了个程序,在DLL中用malloc分配了一块内存,但是在exe程序中释放,结果程序crash,原因就是:其原因可能是堆被损坏,这也说明 TestMySticker.exe 中或它所加载的任何 DLL ...

  6. Linux C 堆内存管理函数malloc()、calloc()、realloc()、free()详解

    C 编程中,经常需要操作的内存可分为下面几个类别: 堆栈区(stack):由编译器自动分配与释放,存放函数的参数值,局部变量,临时变量等等,它们获取的方式都是由编译器自动执行的 堆区(heap):一般 ...

  7. malloc与new的区别

    1.new是运算符,而malloc是库函数 2.new可以重载,可以自定义内存分配策略,甚至不做内存分配,甚至分配到非内存设备上.而malloc不能. 3.new在用于定义一个新的非内部对象的时候,默 ...

  8. new 等于 malloc加构造函数

    1.new 是c++中的操作符,malloc是c 中的一个函数 2.new 不止是分配内存,而且会调用类的构造函数,同理delete会调用类的析构函数,而malloc则只分配内存,不会进行初始化类成员 ...

  9. 关于malloc函数的动态分配问题

    malloc函数动态分配了一个整型的内存空间,让abc都指向刚申请的空间,所以只有最后一个赋值语句的值保留在了空间里 #include<stdio.h> main() { int *a,* ...

  10. 转:如何实现一个malloc

    如何实现一个malloc 转载后排版效果很差,看原文!   任何一个用过或学过C的人对malloc都不会陌生.大家都知道malloc可以分配一段连续的内存空间,并且在不再使用时可以通过free释放掉. ...

随机推荐

  1. dp,px,pt,sp 的区别 以及dp 和 px 互转

    dp = dip : device independent pixels(设备独立像素). 不同设备有不同的显示效果,这个和设备硬件有关,一般我们为了支持WVGA.HVGA和QVGA 推荐使用这个,不 ...

  2. 关于css盒模型

    在css中,width和height指的是内容区域的宽度和高度.增加内边距,边框和外边距不会影响内容区域的尺寸,但是会增加元素框的总尺寸.假设框的每个边上有10个像素的外边距和5像素的内边距,如果希望 ...

  3. 关于Java的散列桶, 以及附上一个案例-重写map集合

    为速度而散列: SlowMap.java说明了创建一个新的Map并不困难.但正如它的名称SlowMap所示,它不会很快,如果有更好的选择就应该放弃它.它的问题在于对键的查询,键没有按照任何特定的顺序保 ...

  4. jsp页面日期格式不正确

    第一种: 如果是从数据库获取的时间(数据库中日期格式是乱的)可以在数据库取数据时   进行格式化   例如  ;TO_CHAR(SYSDATE,'YYYY-MM-DD') 第二种: 在数据库取出数据后 ...

  5. 【转】IntelliJ IDEA中文乱码问题

    1.首先是编辑器的乱码,这个很好解决,file->settings->appearence里面有个Name设置成支持中文的字 体(这个很重要) 同样还要再settings中的Eidtor- ...

  6. 几种扫描二维码工具的User-Agent

    微信: user-agent: Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_3 like Mac OS X) AppleWebKit/603.3.8 (KHTML, ...

  7. [ 搭建Redis本地服务器实践系列三 ] :图解Redis客户端工具连接Redis服务器

    上一章 [ 搭建Redis本地服务器实践系列二 ] :图解CentOS7配置Redis  介绍了Redis的初始化脚本文件及启动配置文件,并图解如何以服务的形式来启动.终止Redis服务,可以说我们的 ...

  8. linux编译安装时常见错误解决办法

    This article is post on https://coderwall.com/p/ggmpfa 原文链接:http://www.bkjia.com/PHPjc/1008013.html ...

  9. 安装VirtualBox中的增强功能包VBoxLinuxAdditions

    首先,增强功能包VBoxLinuxAdditions有什么作用呢?请看: (1)实现客户机和主机间的鼠标切换. (2)与主机实现文件共享. (3)自动调整客户机分辨率. (4)与主机共享剪贴板的内容. ...

  10. JFrame图形界面 ----鼠标消息

    #开始 不管是什么GUI 按钮的存在都是必不可少的而且还会有很多奇怪的按钮 #代码 package window; import java.awt.Container; import java.awt ...