重载new和delete

1. 测试代码:

 #include<iostream>
#include<new>
using namespace std;
class A {
public:
A() { cout << "A constructor" << endl; } void* operator new(size_t size)
{
cout << "this is A's new" << endl;
return ::operator new(size);
} void operator delete(void* ptr)
{
cout << "this is A's delete" << endl;
return ::operator delete(ptr);
} ~A() { cout << "A destructor" << endl; }
}; int main()
{
A *a = new A;
delete a;
return ;
}

运行结果:

虽然我们不能改变new/delete的行为,但是通过重载operator new() 和 operator delete()我们可以实现自己想要的内存管理方式,这在内存池的实现中十分关键。关于operator new有几点要注意:

(1)当无法满足所要求分配的空间时,则如果有new_handler,则调用new_handler,否则如果没要求不抛出异常(以nothrow参数表达),则执行bad_alloc异常,否则返回0

(2)重载时,返回类型必须声明为void*

(3)重载时,第一个参数类型必须为表达要求分配空间的大小(字节),类型为size_t

(4)重载时,可以带除(3)以外的其它参数

2.测试代码:

 #include <iostream>
#include <new>
#include <cstdlib>
using namespace std; void* operator new(size_t size)
{
cout << "global Override operator new: " << size << endl;
void * ptr = malloc(size);
return ptr;
} void* operator new(size_t size, int flag)
{
cout << "global Override operator new: " << size << " " << flag << endl;
return (::operator new(size));
} void operator delete (void* ptr)
{
cout << "global Override operator delete" << endl;
free(ptr);
ptr = nullptr;
} void operator delete (void* ptr, int flag)
{
cout << "Override operator delete: " << flag << endl;
::operator delete(ptr);
ptr = nullptr;
}
int main() {
int * ptr = new int();
delete ptr;
cout << endl << "*********************" << endl << endl;
ptr = new() int();
delete ptr;
return ;
}

输出结果:

定位new表达式

1. 测试代码:

 #include <iostream>
using namespace std;
char addr1[];
int main()
{
cout << "******定位new表达式演示***by David***" << endl;
char addr2[];
char *addr3 = new char[];
cout << "addr1 = " << (void*)addr1 << endl;
cout << "addr2 = " << (void*)addr2 << endl;
cout << "addr3 = " << (void*)addr3 << endl;
int *p = nullptr; p = new(addr1)int; ////把内存分配到静态区
*p = ;
cout << (void*)p << " " << *p << endl; p = new(addr2)int; ////把内存分配到栈区
*p = ;
cout << (void*)p << " " << *p << endl; p = new(addr3)int; //把内存分配到堆区
*p = ;
cout << (void*)p << " " << *p << endl;
return ;
}

运行结果:

2.测试代码

 #include <iostream>
#include <string>
#include <new> using namespace std;
const int BUF = ; class JustTesting {
private:
string words;
int number;
public:
JustTesting(const string &s = "Just Testing", int n = )
{
words = s;
number = n;
cout << words << " constructed\n";
} ~JustTesting() { cout << words << " destroyed\n"; }
void Show() const { cout << words << ", " << number << endl; }
}; int main(void)
{
char *buffer = new char[BUF]; // get a block of memory
JustTesting *pc1, *pc2; pc1 = new (buffer)JustTesting; // place object in buffer
pc2 = new JustTesting("heap1", ); // place object on heap cout << "Memory block address:\n" << "buffer: "
<< (void *)buffer << " heap: " << pc2 << endl;
cout << "Memory contents: \n";
cout << pc1 << ": ";
pc1->Show();
cout << pc2 << ": ";
pc2->Show(); JustTesting *pc3, *pc4;
pc3 = new (buffer) JustTesting("bad Idea", );
pc4 = new JustTesting("Heap2", ); cout << "Memory contents: \n";
cout << pc3 << ": ";
pc3->Show();
cout << pc4 << ": ";
pc4->Show(); delete pc2; // free heap1
delete pc4; // free heap2
delete[] buffer; // free buffer
cout << "Done\n"; return ;
}

运行结果:

参考资料

【C++ Primer | 19】控制内存分配的更多相关文章

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

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

  2. [C++] 重载new和delete——控制内存分配

      1.new和delete表达式的工作机理      1)new表达式实际执行了三步 string *sp=new string("aaaa"); ];//string采用默认初 ...

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

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

  4. c++控制内存分配

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

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

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

  6. 《C++ Primer Plus》读书笔记之十—类和动态内存分配

    第12章 类和动态内存分配 1.不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存.可以在类声明之外使用单独的语句进行初始化,这是因为静态类成员是单独存储的,而不是对象的 ...

  7. C++ primer plus读书笔记——第12章 类和动态内存分配

    第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...

  8. C++ Primer 学习笔记_98_特殊的工具和技术 --优化内存分配

    特殊的工具和技术 --优化内存分配 引言: C++的内存分配是一种类型化操作:new为特定类型分配内存,并在新分配的内存中构造该类型的一个对象.new表达式自己主动执行合适的构造函数来初始化每一个动态 ...

  9. 【转载】C++内存分配

    原文:C++内存分配 内存泄露相信对C++程序员来说都不陌生.解决内存泄露的方案多种多样,大部分方案以追踪检测为主,这种方法实现起来容易,使用方便,也比较安全. 首先我们要确定这个模块的主要功能: 能 ...

随机推荐

  1. 把svn上的mycelipse导到本地的eclipse中【原】

    myeclipse和eclipse的web项目互导时会产生各种问题,现在把我遇到的情况记录如下: eclipse如何把svn上down下来的myeclipseWeb项目变成eclipse的Web项目: ...

  2. CentOS6.8下Jenkins+maven+tomcat+git+shell自动构建、部署web应用环境的搭建

    参考资料:http://www.cnblogs.com/cheng95/p/6542036.html http://www.cnblogs.com/software-test/p/7068278.ht ...

  3. python学习笔记8--面向对象编程

    一.面向对象编程 面向对象--Object Oriented Programming,简称oop,是一种程序设计思想.在说面向对象之前,先说一下什么是编程范式,编程范式你按照什么方式来去编程,去实现一 ...

  4. MongoDB - 日常操作二

    MongoDB 开启认证与用户管理  ./mongo # 先登录 use admin # 切换到admin库 db.addUser(") # 创建用户 db.addUser('zhansan ...

  5. NOIP2018ty记

    前置传送门:noip2018前流水账 Day-inf~Day-3 写流水账里了 懒得再写了 Day-2~Day-1 做了些noip的原题 真是奇怪,我天天爱跑步和逛公园都是1A的,结果反而有些普及组的 ...

  6. drozer工具的安装与使用:之一安装篇

    本教程针对于Windows平台下drozer的安装与使用   使用该工具需要JDK的支持,所以使用此工具之前请自行安装 JDK(如有问题的请自行百度其他教程,这里就不赘述了)   还需要安卓调试工具a ...

  7. 深入剖析ThreadLocal实现原理以及内存泄漏问题

    关于ThreadLocalMap<ThreadLocal, Object>弱引用问题: 当线程没有结束,但是ThreadLocal已经被回收,则可能导致线程中存在ThreadLocalMa ...

  8. springMVC入门(一)

    1.   SpringMVC入门 1.1SpringMVC是什么 Spring web mvc和Struts2都属于表现层的框架,它是Spring框架的一部分,我们可以从Spring的整体结构中看得出 ...

  9. Linux内核驱动之GPIO子系统(一)GPIO的使用【转】

    转自:http://blog.csdn.net/tommy_wxie/article/details/9427047 一 概述 Linux内核中gpio是最简单,最常用的资源(和 interrupt  ...

  10. WebRTC服务器——Licode 环境搭建

    WebRTC服务器--Licode 环境搭建 系统配置 阿里云服务器 Ubuntu 14.04.5 LTS Docker 环境搭建 在一台空的机器上搭建docker环境,先要安装docker,执行下面 ...