zoukankan      html  css  js  c++  java
  • 谈谈new 与delete

    任何一个C++程序员对这两个运算符都很熟悉,不就是生成和释放一个对象嘛。但是当我们需要自己管理对象的内存分配行为时,有必要好好讨论一番。先介绍一下几个概念:

    1.        内存申请

    new operator: 如 string *ps = new string(“Memory Management”);

    上述语句做了两方面的工作:第一,分配了一个足够存放一个string对象的内存;第二,调用string类的constructor,为string对象设定初值。至于想自己管理对象的内存分配策略,就得重载operator new,但第二步却不能够改变,也不应该改变。

    operator new: 我们可以重载operator new来改变用来容纳对象的内存的分配行为。函数operator new 通常声明如下:

    void * operator new(size_t size);

    其返回值为void *,指向一块raw memory,参数size表示分配多少内存。

    重载之后你也可以直接调用operator new如下:

    void *rawMemory = operator new(sizeof(string));

    这本质上和使用 void *rawMemory = malloc(sizeof(string));一样,只负责了内存的分配。

    从上面的new operator和operator new 分析中,可以看出:

    string *pStr = new string(“hello”);

    实际上会进行的动作可分解为:

    1 void *rawMemory = operator new(sizeof(string));//分配原始内存

    2 调用constructor 初始化rawMemory     

    3 string *ps = static_cast<string*>(memory);  //让pStr 指向新完成的对象

    下面谈谈new operator 的另一种用法,称为placement new,当程序使用共享内存或内存映射机制时,这类函数可能是有用的。下面我们来看看他的真面目,范例如下:

    string * constructStringInBuffer(void*buffer, int size)    //返回内存地址

    {

           returnnew (buffer) string(size);

    }

    上述中的new (buffer) string(size)是new operator 的用法之一,在STL中的容器alloctor中被广泛使用。

    总结一下上述new operator, operator new 及placement new 的区别:new operator 用于在堆中生成对象,而placement new是new operator的一种用法,用于在一块已知的内存中构造对象, operator new 只是分配了内存,并不会调用对象的构造函数。

    2.        内存释放

    既然申请了内存,当然还要关心会不会产生内存泄露。内存释放动作是由函数operator delete执行,通常声明如下:

    void operator delete(void *memory);

    而执行delete pStr;相当于执行

    ps->~string();

    operator delete(ps);    //从这边也可以看出operator delete与operator new是配套的

    这边表明了如果你不打算调用对象的析构函数来释放内存,就应该用operator delete来处理operator new 生成的内存。

    需要注意的是如果你使用placement new,你应该避免对那块内存调用 delete operator,(因为要析构对象); 但是同样你也不能通过直接调用delete pStr; (调用析构函数后调用operator delete)。因为对象使用的内存并不来自operator new.这时就应该手动释放。范例如下:

    void * mallocShare(size_t size);

    void * freeShared(void*memory);   //这一对函数配套使用,用于申请和释放内存

    void *shareMemory = mallocShare(sizeof(string));

    string *pStr = constructStringInBuffer(shareMemory,sizeof(string));

    pStr->~string();

    freeShard(pStr);

    参考资料:More Effective C++

  • 相关阅读:
    数据库设计
    构建评价
    Schema xds文献
    架构设计评价
    需求分析评价
    获取script的链接参数并执行
    js获取封装对象/通过id tag className
    通过css/js来固定div的位置
    nginx日志分析工具goaccesss
    如何快速安装 allure
  • 原文地址:https://www.cnblogs.com/OpenLinux/p/5020704.html
Copyright © 2011-2022 走看看