【C++ Primer | 19】控制内存分配
重载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】控制内存分配的更多相关文章
- C++ Primer 笔记——控制内存分配
1.当我们使用一条new表达式时,实际执行了三步操作. new表达式调用一个名为operator new ( 或者operator new[] ) 的标准库函数.该函数分配一块足够大的,原始的,未命名 ...
- [C++] 重载new和delete——控制内存分配
1.new和delete表达式的工作机理 1)new表达式实际执行了三步 string *sp=new string("aaaa"); ];//string采用默认初 ...
- C++之控制内存分配
一.内存分配方式 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区.栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释 ...
- c++控制内存分配
为了满足应用程序对内存分配的特殊需求,C++允许重载new运算符和delete运算符控制内存分配,通过定位new表达式初始化对象(好处是可以在某些场景下避免重新内存分配的消耗) 1.operate n ...
- C++ 内存分配操作符new和delete详解
重载new和delete 首先借用C++ Primer 5e的一个例子: string *sp = new string("a value"); ]; 这其实进行了以下三步操作: ...
- 《C++ Primer Plus》读书笔记之十—类和动态内存分配
第12章 类和动态内存分配 1.不能在类声明中初始化静态成员变量,这是因为声明描述了如何分配内存,但并不分配内存.可以在类声明之外使用单独的语句进行初始化,这是因为静态类成员是单独存储的,而不是对象的 ...
- C++ primer plus读书笔记——第12章 类和动态内存分配
第12章 类和动态内存分配 1. 静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域运算符来指出静态成员所属的类.但如果静态成员是整形或枚举型const,则可以在类声明中初始化 ...
- C++ Primer 学习笔记_98_特殊的工具和技术 --优化内存分配
特殊的工具和技术 --优化内存分配 引言: C++的内存分配是一种类型化操作:new为特定类型分配内存,并在新分配的内存中构造该类型的一个对象.new表达式自己主动执行合适的构造函数来初始化每一个动态 ...
- 【转载】C++内存分配
原文:C++内存分配 内存泄露相信对C++程序员来说都不陌生.解决内存泄露的方案多种多样,大部分方案以追踪检测为主,这种方法实现起来容易,使用方便,也比较安全. 首先我们要确定这个模块的主要功能: 能 ...
随机推荐
- GUI之ScrollView的使用
ScrollView ScrollView是unity提供的一个方便的滚动视图. 组成 ScrollView由四个部分组成: ViewPort 和 Content ScrollView: 视图范围,C ...
- idea_2018.1.5版本的激活使用
1:步骤help中找到register,然后按如下截图操作 注册码: K71U8DBPNE-eyJsaWNlbnNlSWQiOiJLNzFVOERCUE5FIiwibGljZW5zZWVOYW1lIj ...
- android HttpClient将数据提交到服务器
1.HttpClient 使用方式 public static String loginByClientGet(String username,String password) { try { //打 ...
- matplotlib-2D绘图库
安装 python -m pip install matplotlib 允许中文: 使用matplotlib的字体管理器指定字体文件 plt.rcParams['font.sans-serif'] ...
- JavaScript之Array/数组小结
MDN-Array的属性/方法:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Arr ...
- 如何手动删除服务?Windows手动删除服务列表中残留服务的方法
https://www.jb51.net/os/windows/267738.html
- ubuntu14.04 安装Kdevelop 进行ROS开发
1. 安装gcc sudo apt-get build-dep gcc sudo apt-get install build-essential 2. 安装Kdevelop sudo apt-get ...
- C++学习2--坦克大战编写-前置知识
基础班学习的这一个多月里的前三周讲解基础的语法,最后一周需要做坦克大战的项目巩固提高自己掌握的语法知识.这个系列博文主要是为了把学习过程中的知识点总结并记录下来: 开发语言与开发工具:C++,VS20 ...
- 【转】Shell编程基础篇-下
[转]Shell编程基础篇-下 1.1 条件表达式 1.1.1 文件判断 常用文件测试操作符 常用文件测试操作符 说明 -d文件,d的全拼为directory 文件存在且为目录则为真,即测试表达式成立 ...
- Protobuf使用手册
Protobuf使用手册 第1章 定义.proto 文件 首先我们需要编写一个 proto 文件,定义我们程序中需要处理的结构化数据,在 protobuf 的术语中,结构化数据被称为 Message. ...