c++ 关于new文件
new文件用来管理c++的动态内存,这个文件声明了几个全局空间的函数(不是std空间的函数,全局空间的函数调用时是用全局作用域解析符),包括operator new 和operator delete的重载 ,这些函数用于处理动态存储空间请求。
其new的头文件源代码
#ifndef _NEW
#define _NEW #include <cstddef>
#include <exception> extern "C++" { namespace std
{ //注意此空间内函数或者变量处于std空间,使用时需要添加std::调用
/**
* 当内存分配错误的时候抛出bad_alloc异常
*/
class bad_alloc : public exception
{
public:
bad_alloc() throw() { }
virtual ~bad_alloc() throw();
}; //当内存分配失败时用此结构体替代异常,使用嵌入式环境,嵌入式环境没有异常功能
struct nothrow_t { };
extern const nothrow_t nothrow; ///当内存分配失败时,调用new_handler
///new_handler试着去分配更多得存储空间,当且仅当申请内存成功时,才会返
///否则抛出bad_alloc异常或者终止程序(调用abort或者exit)
typedef void (*new_handler)();
new_handler set_new_handler(new_handler) throw();
} // namespace std //全局空间函数,调用时加上作用域解析符,如::operator new ()
void* operator new(std::size_t) throw (std::bad_alloc);
void* operator new[](std::size_t) throw (std::bad_alloc);
void operator delete(void*) throw();
void operator delete[](void*) throw();
void* operator new(std::size_t, const std::nothrow_t&) throw();
void* operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw(); //placement operator new/delete inline void* operator new(std::size_t, void* __p) throw() { return __p; }
inline void* operator new[](std::size_t, void* __p) throw() { return __p; } inline void operator delete (void*, void*) throw() { }
inline void operator delete[](void*, void*) throw() { } } // extern "C++" #endif
1、关于new operator与operator new
operator new() 仅仅分配内存空间,是对malloc的一个封装,返回的是一个void *,如
int* a = (int *)::operator new(sizeof(int));
只是对a分配了空间,通过vs2012进行调试你会发现operator new 的实现如下:其主要是调用malloc(size),而没有对内存进行初始化
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc) { // try to allocate size bytes
void *p;
while ((p = malloc(size)) == )
if (_callnewh(size) == )
{ // report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
对于new operator先调用operator new分配内存空间,然后调用构造函数初始化
#include <iostream>
using namespace std; class Foo{
public:
Foo(){
cout<<"Foo constructor"<<endl;
a = ;
} //对operator new进行重写
void* operator new(size_t size){
cout<<"Foo operator new"<<endl;
return ::operator new(size);
} int a;
}; int main(){
Foo* f1 =(Foo *) ::operator new(sizeof(Foo));
cout<<f1->a<<endl;
Foo* f2 = new Foo();
cout<<f2->a<<endl;
} /***************
结果为:
3420040
Foo operator new
Foo constructor
10 *****************/
由于operator new 只是分配空间未调用构造函数,所以公有变量未初始化,是个随机值,
而new Foo() 先调用operator new 然后再构造函数,所以会先出现Foo operator new
2、关于placement new(定位放置new)
placement new 是operator new的一个重载的版本,如果你想在已经分配的内存中创建一个对象,这时不能使用new。而placement new永许你在一个已经分配好的内存中(栈或者堆中)构造一个新的对象,原型中void* p实际就是指向一个已经分配好的内存缓冲区的首地址。c++支持placement operator new,能够在预先分配的缓冲区中构造对象,避免new内存分配时查找内存和分配内存的时间,而且由于内存已经分配,没有内存分配失败的危险,在内存池,垃圾回收器,和性能或异常安全可以使用
char *buf = new char[sizeof(string)]; // pre-allocated buffer
string *p = new (buf) string("hi"); // placement new
char memory[sizeof(Foo)];
void* place = memory; Foo* f = new(place) Foo();
3、关于set_new_handler
new_handler类型的函数是默认内存申请函数(operator new和operator new[])申请内存失败,会被调用。
new_handler函数会试图为新的内存申请请求提供更多的可用空间。当且仅当,函数成功地提供了更多的可用空间,它才返回。
否则,要么抛出bad_alloc异常(或bad_alloc派生类)要么终止程序(比如调用abort或exit)。
如果new_handler函数返回(即,它提供了更多可用空间)后,当内存申请函数申请指定的内存空间失败时,它会被再次调用,或直到new_handle函数不返回或被替换。
#include <iostream>
#include <new> char* memoryPool = NULL; void my_new_handler(){
if(NULL != memoryPool){
// 删除一些不用的内存
delete[] memoryPool;
memoryPool = NULL;
}else{
//没有足够的内存
throw std::bad_alloc();
}
return ;
} int main(){
std::set_new_handler(my_new_handler);
memoryPool = new char[**];
if(memoryPool == NULL){
std::cout<<"allocator fail"<<std::endl;
return -;
}
char *p = NULL;
for(int i = ; i < ; ++ i){
p = new char[**];
std::cout<<i+<<" allocator 512M "<<p<<std::endl;
}
return ;
}
c++ 关于new文件的更多相关文章
- Mapreduce的文件和hbase共同输入
Mapreduce的文件和hbase共同输入 package duogemap; import java.io.IOException; import org.apache.hadoop.co ...
- mapreduce多文件输出的两方法
mapreduce多文件输出的两方法 package duogemap; import java.io.IOException; import org.apache.hadoop.conf ...
- 01.SQLServer性能优化之----强大的文件组----分盘存储
汇总篇:http://www.cnblogs.com/dunitian/p/4822808.html#tsql 文章内容皆自己的理解,如有不足之处欢迎指正~谢谢 前天有学弟问逆天:“逆天,有没有一种方 ...
- SQL Server 大数据搬迁之文件组备份还原实战
一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 解决方案(Solution) 搬迁步骤(Procedure) 搬迁脚本(SQL Codes) ...
- SQLSERVER将一个文件组的数据移动到另一个文件组
SQLSERVER将一个文件组的数据移动到另一个文件组 有经验的大侠可以直接忽视这篇文章~ 这个问题有经验的人都知道怎麽做,因为我们公司的数据量不大没有这个需求,也不知道怎麽做实验 今天求助了QQ群里 ...
- SQL Server中的高可用性(2)----文件与文件组
在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性.在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性.SQL Server允许在某些文件损坏或离线的情况下,允 ...
- C# ini文件操作【源码下载】
介绍C#如何对ini文件进行读写操作,C#可以通过调用[kernel32.dll]文件中的 WritePrivateProfileString()和GetPrivateProfileString()函 ...
- 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用
有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...
- 【原】Android热更新开源项目Tinker源码解析系列之二:资源文件热更新
上一篇文章介绍了Dex文件的热更新流程,本文将会分析Tinker中对资源文件的热更新流程. 同Dex,资源文件的热更新同样包括三个部分:资源补丁生成,资源补丁合成及资源补丁加载. 本系列将从以下三个方 ...
- GreenDao 数据库:使用Raw文件夹下的数据库文件以及数据库升级
一.使用Raw文件夹下的数据库文件 在使用GreenDao框架时,数据库和数据表都是根据生成的框架代码来自动创建的,从生成的DaoMaster中的OpenHelper类可以看出: public sta ...
随机推荐
- 解决passwd 为普通用户设密码 不成功的方法
echo "xxxxxxxxx"|passwd --stdin user_name #这样设置密码就可以成功!
- linux中解决SSH连接慢问题 关键点GSSAPIAuthentication
[root@ok 6FE5-D831]# ssh -v xxx.xxx.xxx.64 OpenSSH_5.3p1, OpenSSL Feb debug1: Reading configuration ...
- Android性能优化系列 + Android官方培训课程中文版
Android性能优化典范 - 第6季 http://hukai.me/android-performance-patterns-season-6/ Android性能优化典范 - 第5季 htt ...
- 谈谈Delphi中的类和对象1---介绍几个概念 && 对象是一个地地道道的指针
参考:http://blog.163.com/liang_liu99/blog/static/88415216200952123412180/ 以下的介绍主要针对的是Delphi的面向对象的知识,可能 ...
- 【JAVA网络流之TCP与UDP 】
一.ServerSocket java.lang.Object |-java.net.ServerSocket 有子类SSLServerSocket. 此类实现服务器套接字.服务器套接字等待请求通过网 ...
- 无废话ExtJs 入门教程二[Hello World]
无废话ExtJs 入门教程二[Hello World] extjs技术交流,欢迎加群(201926085) 我们在学校里学习任何一门语言都是从"Hello World"开始,这里我 ...
- 使用AStyle进行代码格式化
转自:http://www.cnblogs.com/JerryTian/archive/2012/09/20/AStyle.html 在日常的编码当中,大家经常要遵照一些设计规范,如命名规则.代码格式 ...
- 注解:【有连接表的】Hibernate单向N->1关联
Person与Address关联:单向N->1,[有连接表的] Person.java package org.crazyit.app.domain; import javax.persiste ...
- android 消息推送
android 消息推送 极光推送百度云推送(语音)友盟消息推送
- "Project facet Java version 1.7 is not supported"的问题解决的办法
问题描述 在eclipse中,从SVN中检出project代码,拖拽式部署到local server中的时候,报出以下错误: 问题分析 问题产生的原因是,SVN中的代码是采用java 1.7开发编译的 ...