C++ new关键字简介

一.new的基本用法

1.c++通过new关键字进行动态分配内存。

2.new开辟的空间存储在堆上,而我们定义的变量存储在栈上。

3.new分配的空间使用delete释放,new[] 使用 delete[]。

4.

int* pi = new int(5);//表示动态分配一个int ,初始化为 5
int* pa = new int[5];//表示动态分配一个数组,数组大小为5

二.new和malloc的区别

1.malloc与free是C++/C语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。

2.对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。 由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。

3.new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换;malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。

4.new内存分配失败时,会抛出bac_alloc异常,它不会返回NULL;malloc分配内存失败时返回NULL。

5.使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算;malloc则需要显式地指出所需内存的尺寸。

三.应用

//这看起来似乎是一个单一运算,它其实是由两个步骤完成。
//这里的new 相当于 new operator
int *pi = new int(5);

1.通过适当的new运算符函数实例,配置所需的内存:

int *pi = __new(sizeof(int));

2.将配置得来的对象设立初值:

*pi = 5;

更进一步地说,初始化操作应该在内存配置成功(经由new运算符)后才执行。

3.delete运算符情况类似。

delete pi;

如果pi的值为0,c++语言会要求delete运算符不要有操作。因此编译器必须为此调用构造一层保护膜:

if(pi != 0)
{
    __delete(pi);
}

注意:pi并不会因此被自动清除为0;

4.new operator

就是我们平常用的new

new operator实际上执行了以下几个步骤:

①调用operator new分配内存。

如果类本身未定义operator new,那么会调用全局的operator new。

// 全局 operator new
void * operator new(std::size_t size) throw(std::bad_alloc)
{
    if (size == 0)
    {    
        size = 1;
    }
    void* p;
    while ((p = ::malloc(size)) == 0) 
    { //采用 malloc 分配空间
        std::new_handler nh = std::get_new_handler();
        if (nh)
            nh();
        else
            throw std::bad_alloc();
    }
    return p;
}

每个类可以重载operator new(),如果类自己定义了operator new(),则调用自己的定义的 operator new,而不是全局的。

通过定义可以发现operator new()只是分配了内存空间。

②通过placement new来调用构造函数

void* operator new (std::size_t size, void* ptr) noexcept;

placement new不需要抛出异常,因为它自身不分配内存。 

ptr指针是已经分配好的,可能在栈上也可能在堆上。

placement new仅在一个已经分配好的内存指针上调用构造函数,placement new 知道如何用就可以了,是编译器编译时候做的事情,不需要我们控制。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章