1、new和delete表达式的工作机理
    
1)new表达式实际执行了三步
string *sp=new string("aaaa");
string *arr=new string[];//string采用默认初始化
     a、调用一个名为operator new(或者operator new[])的标准库函数,分配一块足够大的、原始的、未命名的内存空间,来准备存储对象或者对象的数组;
     b、编译器运行相应的构造函数构造这些对象,在这里运行的是string的构造函数;
     c、返回一个指向该对象或者对象数组的指针。
 
2)delete执行了两步操作:
delete sp;
delete []arr;
      a、对sp或者arr所指的数组中的元素执行相应的析构函数;
      b、编译器调用名为operator delete或者operator delete[]的标准库函数释放内存空间。
 
所以,想要控制内存分配,需要重载标准库函数中的operator new和operator delete函数,可以在类中重载,也可以在类外(全局)重载;使用作用域运算符::可以忽略类中的函数,直接执行全局作用域中的版本,::operator new,::operator delete。
 
2、标准库函数中的operator new 和operator delete
#ifndef _NEWANDDELETE_H_
#define _NEWANDDELETE_H_
#include<new>
#include<cstdlib>
using namespace std; class NewAndDelete {
public:
/**
* 以下是标准库函数中的operate new和operator delete
* 前面4个会抛出异常,后面4个不会抛出异常
* 这几个运算符函数是隐式静态的,因为operator new在构造对象之前,用来分配空间;operator delete在对象销毁之后,用来释放空间
* operator new 或者operator new[]的返回类型必须是void*,第一个形参类型必须是size_t并且没有默认实参,size_t代表要分配的空间的大小
* operator delete或者operator delete[]返回类型必须是void,第一个形参类型必须是void*,用指向待释放内存的指针来初始化
* 这两个函数的行为与allocator类中allocate()和deallocate()很类似
*/
static void *operator new(size_t);
static void *operator new[](size_t);
static void operator delete(void*)noexcept;
static void operator delete[](void*)noexcept; static void *operator new(size_t, nothrow_t&)noexcept;
static void *operator new(size_t, nothrow_t&)noexcept;
static void operator delete(void*, nothrow_t&)noexcept;
static void operator delete[](void*, nothrow_t&)noexcept;
}; //实现示例——使用malloc和free
void* NewAndDelete::operator new(size_t size) {
if (void *mem = malloc(size))
return mem;
else
throw bad_alloc();//抛出异常
}
void NewAndDelete::operator delete(void *mem)noexcept {
free(mem);
}
void* NewAndDelete::operator new(size_t size, nothrow_t& no)noexcept {//不抛出异常,返回空指针
void *p;
if (void *mem = malloc(size))
return mem;
else return p;
}
void NewAndDelete::operator delete(void *mem, nothrow_t& no)noexcept {
free(mem);
}
#endif

[C++] 重载new和delete——控制内存分配的更多相关文章

  1. C++之控制内存分配

    一.内存分配方式 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区.栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释 ...

  2. c++控制内存分配

    为了满足应用程序对内存分配的特殊需求,C++允许重载new运算符和delete运算符控制内存分配,通过定位new表达式初始化对象(好处是可以在某些场景下避免重新内存分配的消耗) 1.operate n ...

  3. 【C++ Primer | 19】控制内存分配

    重载new和delete 1. 测试代码: #include<iostream> #include<new> using namespace std; class A { pu ...

  4. 重载全局new/delete实现内存检测

    下面介绍用重载new/delete运算符的方式来实现一个简单的内存泄露检测工具,基本思想是重载全局new/delete运算符,被检测代码调用new和delete运算符时就会调用重载过的operator ...

  5. C++编程学习(八)new&delete动态内存分配

    前段时间楼主忙着期末大作业,停更了一段,今天刚好在做机器人课程的大作业时,和同组的小伙伴利用python做了工业机器人的在线编程,突然想起来很久没有阅读大型工程了,马上补上- 接下来的几篇博客主要是博 ...

  6. C++ 自学笔记 new和delete(动态内存分配)

    动态内存分配 Dynamic memoey allocation C++使用new和delete 来申请和释放内存 new:先申请一个空间 int\Stash : 默认构造函数初始化对象 ~:析构函数 ...

  7. C++ Primer 笔记——控制内存分配

    1.当我们使用一条new表达式时,实际执行了三步操作. new表达式调用一个名为operator new ( 或者operator new[] ) 的标准库函数.该函数分配一块足够大的,原始的,未命名 ...

  8. C++ 内存分配操作符new和delete详解

    重载new和delete 首先借用C++ Primer 5e的一个例子: string *sp = new string("a value"); ]; 这其实进行了以下三步操作: ...

  9. 【ThinkingInC++】64、重载new和delete,来模仿内存的分配

    /** * 书本:[ThinkingInC++] * 功能:重载new和delete.来模仿内存的分配 * 时间:2014年10月5日14:30:11 * 作者:cutter_point */ #in ...

随机推荐

  1. egret项目发布为微信小程序

    1.更改游戏的缩放模式 因为微信小游戏不支持showAll,如果你使用了showAll模式.可以改成fixedWidth或fixedHeight.在index.html里修改,如下图 但这个又涉及到了 ...

  2. 前端传递给后端复杂类型 webapi 等

    来自URL:https://www.cnblogs.com/kylewell/p/5674564.html 前端我需要通过ajax 传递如下的一个json对象: var model = { Param ...

  3. Go组件学习——database/sql数据库连接池你用对了吗

    1.案例 case1: maxOpenConns > 1 func fewConns() { db, _ := db.Open("mysql", "root:roo ...

  4. 12.源码分析—如何为SOFARPC写一个序列化?

    SOFARPC源码解析系列: 1. 源码分析---SOFARPC可扩展的机制SPI 2. 源码分析---SOFARPC客户端服务引用 3. 源码分析---SOFARPC客户端服务调用 4. 源码分析- ...

  5. SecureCRT软件的个性化设置

    工欲善其事,必先利其器.如果我们能花点时间把每天工作都要用到的SecureCRT软件设置的舒服一些,日后工作起来也是会心情愉悦.事半功倍的. 1.日志文件设置 2.窗口配色和关键字高亮 3.效果展示 ...

  6. Linux查找命令对比(find、locate、whereis、which、type、grep)

    //太长不看版find查找磁盘空间,相较于locate和whereis速度较慢.find和locate的查找单位为文件或者目录,locate其实是find -name的另一种写法.locate和whe ...

  7. alter add命令用来增加表的字段

    alter add命令格式:alter table 表名 add字段 类型 其他; 例如,在表MyClass中添加了一个字段passtest,类型为int(4),默认值为0: mysql> al ...

  8. Gym - 101252H

    题意略. 思路:二分.注意当利率高且m比较小的时候,每个月的偿还可能会大于本金,所以我们二分的右边界应该要设为2 * 本金. 详见代码: #include<bits/stdc++.h> # ...

  9. MSIL实用指南-生成for语句

    for语句格式是这样的for(<初始化语句>;<条件语句>;<自增减语句>) <循环体> 它可以转换为while语句 if(<条件语句>){ ...

  10. Oracle数据库中心双活之道:ASM vs VPLEX (转)

    双活方案对比:ASM vs V-PLEX 作者:王文杰 Oracle公司 Principle system analyst Oracle高级服务部 Oracle数据库中心的灾备的演变,经历了多年的演变 ...