我是靠谱客的博主 唠叨冰棍,最近开发中收集的这篇文章主要介绍C++ new的时候判断null空指针操作可能成为bug,需要这么改1.new异常的结果2.全局重装new和delete,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
1.new异常的结果
在C++中,通过new分配内存时,假如内存不够,会根据编译器版本不同来处理异常,对于老的编译器,会返回null空指针(和malloc一样).但是目前大多数标准编译器都是直接抛出异常的.
测试代码如下所示:
try
{
for (int i = 0 ; i<1000;i++) { // 不停new,直到new分配失败为止
double *ptr=new double[1000000];
cout<<"i = "<< i <<" ptr = "<<ptr<<endl;
}
}
catch(bad_alloc &memExp)
{
cerr<<memExp.what()<<endl;
}
运行打印:
所以下面这样类似的代码在目前大多数标准编译器是没有意义的:
int* p = new int[size];
if ( p == 0 ) // 检查 p 是否空指针
return -1;
因为分配失败是直接抛出异常!还会误导其他人,并且可能出现bug.
所以为了不区分编译器版本,统一差异,我们需要重载new和delete,并且除此之外我们还可以统计使用的动态内存信息。
重载new和delete有两种方式:
- 1. 重载全局的new和delete操作符函数
- 2. 重载类成员的new和delete,项目中定义一个基类,比如Object或者Base等类来实现
2.全局重装new和delete
我们以全局重装new和delete为例, 首先定义一个heap.h头文件,内容如下所示:
#ifndef HEAP_H
#define HEAP_H
#include <cstdlib>
#include <iostream>
using namespace std;
void *operator new(unsigned int sz)
{
cout<<"operator new size:"<<sz<<endl;
void *m=malloc(sz);
if(!m)
cout<<"new out of memory!"<<endl;
return m;
}
void operator delete(void* p) noexcept // noexcept该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。 C++11之前是用的throw()
{
free(p);
}
void *operator new[](unsigned int sz)
{
cout<<"operator new size:"<<sz<<endl;
void *m=malloc(sz);
if(!m)
cout<<"new out of memory!"<<endl;
return m;
}
void operator delete[](void* p) noexcept
{
free(p);
}
#endif // HEAP_H
然后在我们main.cpp包含该头文件,即可实现重载,main.cpp的内容如下所示:
int main()
{
for (int i = 0 ; i<1000;i++) {
double *ptr=new double[1000000];
cout<<"i = "<< i <<" ptr = "<<ptr<<endl;
if (ptr == nullptr) {
break;
}
}
return 0;
}
运行打印:
最后
以上就是唠叨冰棍为你收集整理的C++ new的时候判断null空指针操作可能成为bug,需要这么改1.new异常的结果2.全局重装new和delete的全部内容,希望文章能够帮你解决C++ new的时候判断null空指针操作可能成为bug,需要这么改1.new异常的结果2.全局重装new和delete所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复