• 谈谈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++

  • 相关阅读:
    Python常用模块之sys
    python操作zip文件
    python的os模块
    [Python模块学习]用qrcode模块生成二维码
    os模块os.walk() 方法和os.path.join()的简单使用
    python操作redis详解
    成员变量和局部变量
    类和对象 引用属性和方法举例
    Java String字符串/==和equals区别,str。toCharAt(),getBytes,indexOf过滤存在字符,trim()/String与StringBuffer多线程安全/StringBuilder单线程—— 14.0
    泛型--面向对象8
  • 原文地址:https://www.cnblogs.com/OpenLinux/p/5020704.html
Copyright © 2020-2023  润新知