new/delete用法
来源:互联网 发布:新浪微博数据统计工具 编辑:程序博客网 时间:2024/05/23 10:35
C++提供了new/delete操作符对内存进行动态定理,在使用有两种方式:C++运行库的默认全局方式和自定义实现。
一、C++运行库中的new/delete使用:
1.1、C++标准中关于new/delete的声明
namespace std
{
class bad_alloc;
struct nothrow_t {};
extern const nothrow_t nothrow;
typedef void (*new_handler)();
new_handler set_new_handler(new_handler new_p) throw; // 通常用来自己处理内存分配失败异常
}
void * operator new(std::size_t size) throw(std::bad_alloc); // 分配失败,抛出异常
void * operator new(std::size_t size, const std::nothrow_t &) throw(); // 分配失败,返回0
void * operator delete(void *ptr) throw();
void * operator delete(void *ptr, const std::nothrow_t &) throw();
void * operator new[] (std::size_t size) throw(std::bad_alloc); // 分配失败,抛出异常
void * operator new[] (std::size_t size, const std::nothrow_t &) throw(); // 分配失败,返回0
void * operator delete[](void *ptr) throw();
void * operator delete[](void *ptr, const std::nothrow_t &) throw();
void * operator new(std::size_t size, void *ptr) throw(); // placement new 返回指定位置的内存作为分配的内存
void * operator new[] (std::size_t size, void *ptr) throw(); // placement new 返回指定位置的内存作为分配的内存
void * operator delete(void *ptr, void*) throw();
void * operator delete[] (void *ptr, void*) throw();
1.2、自定义异常处理函数
一般情况下程序员并不对new/delete错误进行处理,而只是交给系统处理,系统调用通过set_new_handler函数设置的默认new_handler函数指针所指向的系统函数,另外还可以由程序员自定义异常处理函数来替换系统函数。Win32系统允许一个进程访问的空间达到4G,其中高2G为系统使用,低2G程序自己使用,下面我们设计一个程序:首先先分配100MB空间,然后进行20次循环,每次分配100MB,执行第19次会失败,此时会调用自己的异常处理函数,释放第一次100MB空间,然后成功申请,第20次时则不会再成功了。
#include <stdio.h>
#include <new>
char *gP = NULL;
void my_new_handler(void)
{
if(gP!=NULL)
{
printf("尝试获取更多的内存......\n");
delete[] gP;
gP = NULL;
}
else
{
printf("不能分配更多的内存......");
throw bad_alloc();
}
return;
}
int main()
{
set_new_handler(my_new_handler); // 安装自定义的异常处理函数
gP = new char[100*1024*1024]; // 首先分配100MB空间
if(gP != NULL)
{
printf("分配的100MB内存地址起始于:0X%x.\n", gP);
}
char *p = NULL;
for(int i=0; i<20; i++)
{
p = new char[100*1024*1024];
printf("%d * 100MB, p = 0X%x\n", i+1, p);
}
printf("完成.\n");
return 0;
}
1.3、关于placement new的用法
下面举个关于placement new的用法:
#include <stdio.h>
#include <new>
int main()
{
char buf[1024];
char *p = new (buffer) char[1024];
printf("buf:\t 0X%x \np:\t0X%x\n", buf, p);
return 0;
}
运行上面程序,可以发现打印出的地址是相同的,说明p获取的内存不是在堆中分配的,而是栈上的内存,所以用过后不用释放,上面语句类似于:
char buf[1024];
char *p = buf;
所不同的是,用new可以分配固定大小的空间给特定的指针使用,这种placement new适用于大量快速建立和销毁小对象的应用。
二、自定义new/delete使用:
2.1、扩展的placement new用法
随着C++标准的发展,上述operator new中可以加上附加参数,仍可归为placement new,这属于自定义重载使用。如下在Debug版下添加自己的处理。
#include <stdio.h>
#include <new>
using namespace std;
void *operator new(size_t n, char* file, int line)
{
printf("size: %d\nnew at %s, %d\n", n, file, line);
printf("now is here: %s", __func__);
return ::operator new(n);
}
void operator delete(void *p, char *file, int line)
{
printf("delete at %s, %d\n", file, line);
printf("now is here: %s", __func__);
::operator delete(p);
return;
}
// __FILE__表示这句所在的源文件名称
// __LINE__表示这句在源文件中的行数,还可以用#line 来指定行数值
// __func__表示该句所在的函数名称
#define new new(__FILE__, __LINE__)
int main()
{
char *p = new char[1024];
operator delete(p, __LINE__);
return;
}
2.2、自定义全局operator new/delete用法
#include <stdio.h>
#include <new>
#include <stdlib.h>
using namespace std;
char *gP = NULL;
void my_new_handler(void)
{
if(gP!=NULL)
{
printf("尝试获取更多的内存......\n");
delete[] gP;
gP = NULL;
}
else
{
printf("不能分配更多的内存......");
throw bad_alloc();
}
return;
}
void *operator new(size_t size)
{
void *p = NULL;
printf("自定义operator new \n");
if(0==size)
return NULL;
while(1)
{
p = malloc(size);
if(p!=NULL)
{
printf("分配成功!\n");
return p;
}
new_hadler gH = set_new_handler(0); // 御载当前内存分配异常函数并返回当前内存分配函数
set_new_handler(gH);
if(gH)
{
printf("调用 new_handler...\n");
(*gH)();
}
else
{
printf("没有内存可分配,也没有new_handler\n");
throw bad_alloc();
}
}
}
void operator delete(void *p)
{
printf("自定义operator delete\n");
return free(p);
}
int main()
{
set_new_handler(my_new_handler); // 安装自定义的异常处理函数
gP = new char[100*1024*1024]; // 首先分配100MB空间
if(gP != NULL)
{
printf("分配的100MB内存地址起始于:0X%x.\n", gP);
}
char *p = NULL;
for(int i=0; i<20; i++)
{
p = new char[100*1024*1024];
printf("%d * 100MB, p = 0X%x\n", i+1, p);
}
printf("完成.\n");
return 0;
}
2.3、自定义类成员函数的operator new/delete用法
operator new/delete可以定义在类体内,此时要作为static成员函数来处理,给所有的类对象使用。
#include <stdio.h>
#include <new>
using namespace std;
class A
{
private:
int m_nVal;
public:
static void * operator new(size_t size);
static void * operator new(size_t size, char *file, int line);
};
void *A::operator new(size_t size, char *file, int line)
{
printf("size: %d\nnew at %s, %d\n", n, file, line);
return ::operator new(size);
}
// new 后面是类名,size则为该类分配的内存空间大小
void *A::operator new(size_t size)
{
printf("size: %d\n", size);
return ::operator new(n);
}
class B: public A
{
private:
int m_nVal;
};
int main()
{
A *pA = new A(); // new的第一个参数是A类的大小
B *pB = new(__FILE__, __LINE__) B(); // new的第一个参数是B类的大小,这是placement new的用法
char *buf = new char[1024]; // 将调用运行库中的operator new
}
派生类对象B所使用的operator new/delete都是继承自A类的,可以通过判断分配空间的大小来对B类作特别处理,或是B类自定义自己的operator new/delete覆盖A类。
if( size != sizeof(A))
return ::operator new(size); // 让B类调用运行库中的operator new
- new/delete 的用法
- new, delete 的用法
- new/delete用法
- new和delete用法
- new与delete正确用法
- new delete的简单用法
- c++ new/delete的用法
- new和delete的用法
- new与delete用法详解
- new和delete的用法
- operator new和operator delete 的用法
- malloc/free和new/delete用法浅析
- new, delete, malloc,free用法心得
- C++中new和delete的用法
- C++中 new和delete的用法
- C++中new和delete的用法
- C++中的new和delete用法
- C++之new和delete的用法
- s*s*-libev配置多端口的最优方法
- 【LeetCode】 231. Power of Two
- 手机抓取数据学习笔记
- Git使用积累
- 求某一天星期几。(基姆拉尔森计算公式)
- new/delete用法
- Longest Common Prefix
- CentOS6.5下MariaDB日志及事物详解和基本操作语句
- LA4258 Metal
- ffmpeg编译参数
- trap 基本介绍
- Something
- Anaconda+Tensorflow+Theano+Keras安装
- memblock -- a simple memory management module