动态内存管理。

C++中通过new和delete运算符进行动态内存管理。
int *p1=new int;
int *p2=new int(3);//3将其初始化为3
int *p3=new int[3]//3表示对象个数。
delete p1;
delete p2;
delete [] p3;

malloc/free与new/delete的区别:
·malloc/free是C/C++标准库的函数,而new/delete是C++操作符。
·malloc/free只是进行申请内存的分配,只能动态申请和释放空间,而new/delete除了能够申请空间和释放空间,还会调用构造函数和析构函数进行初始化和清理工作。
·malloc/free需要手动计算申请的大小,new/delete可自己计算类型的大小,返回对应类型的指针。

操作符new:是一个函数。new/delete与new[]/delete[]的实现是通过以下四个函数实现的,同时以下4个函数可以直接开辟空间
void * operator new (size_t size);
void operator delete (void* p);
void * operator new [](size_t size);
void operator delete[] (void* p);
通过查看这4个函数的源码,作出如下总结
1. operator new/operator delete operator new[]/operator delete[] 和 malloc/free用法一样
2. 他们只负责分配空间/释放空间,不会调调对象构造函数/析构函数来初始化/清理对象。
3. 实际operator new和operator delete只是malloc和free的一层封装。
这四个函数是库函数,并不是运算符的重载。

通过调试:发现:
new做了两件事情:1.调用opertor new()函数分配空间。2.调用构造函数初始化对象。
delete做了两件事情:1.调用析构函数清理对象。2.释放空间。
new []:做了两件事情:1.调用operator new[]函数分配空间。2.调用构造函数初始化对象。
delete[]做了两件事情:1.调用析构函数清理对象,2.释放空间。

另外:用delete[]时没有给出次数,那编译器是如何知道,要调用析构函数的次数呢?
在new []中会多出来的4个字节是用来存放要开辟的对象个数的,将空间的的首地址向后偏移。
A p = new A[3]; int d = ((int*)p - 1);
注意:只有当为类的对象(内置类型)开辟空间,并且该类有自定义的析构函数时,才会有多出的4个字节!

3.定位new表达式:
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
new(place_adress)type
new(place_adress)type(initializer-list)
place_adress必须为一个指针,initializar-list是类型的初始化列表。

4.利用malloc和free实现new/delete/new[]/delete[]

class A
{
public:
        A(int  _a)
               :a(_a)
        {
               cout << "A" << endl;
        }
        ~A()
        {
               cout << "~A" << endl;
        }
private:
        int a;
};
int main()
{
        //new的实现
        A*pa = (A*)malloc(10 * sizeof(A)+4);
        *((int*)pa) = 10;//将第一个占用4字节空间赋值为创建对象的个数
        A*pStart = (A*)((int*)(pa + 1));//     //new操作符返回的地址是开辟的连续空间的向后移4个字节之后的地址 
        for (int i = 0; i < 10; i++)
        {
               new(pStart + i)A(1);//利用定位new表达式
        }
        int n = *(int*)((pStart - 1));
        for (int i = 0; i < n; i++)
        {
               pStart[i].~A();
        }
        //free((int*)pStart - 1);
        operator delete[]((int *)pStart - 1);//调用operator delete[](char *)函数释放内存空间 
        system("pause");
        return 0;
}

猜你喜欢

转载自blog.csdn.net/xiaodu655/article/details/81152933