zoukankan      html  css  js  c++  java
  • new和malloc的联系与区别(上)

    熟悉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的话,是无法直接在上面构造出对象的。

    转载:https://www.cnblogs.com/David-Lin/p/10778237.html

     

     

     

     

     

     

     

  • 相关阅读:
    Qtranslate是Win10系统的一款非常小众的翻译神器,真的是办公人员利器
    大文件查找软件(WizTree) v3.37 ---非常快
    DirPrintOK --- 将文件以树的形式列出、可导出到excel、html文件,用于整理电脑的文件,非常好用
    Linux五大类常用命令
    Android pm list 命令查看手机安装的apk信息
    Android adb命令列出当前设备所有apk安装的路径和包名
    Win10 Python2.7.6 如何使用pip命令?如何离线安装第三方模块?PyCharm设置Python2.7.6,、wxPython安装
    证件照在线免费移除背景或更换背景
    Ubuntu wps办公软件快捷键
    根据书籍的ISBN号查询书籍信息
  • 原文地址:https://www.cnblogs.com/oneDongHua/p/14263986.html
Copyright © 2011-2022 走看看