我是靠谱客的博主 唠叨冰棍,最近开发中收集的这篇文章主要介绍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所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部