new/delete new[]/delete[]

C语言使用malloc/realloc/calloc/free进行内存管理。C++通过操作符new和delete进行内存管理。new/delete动态管理对象,new[]/delete[]动态管理对象数组。

void Test()
{
    int* p1 = new int;//动态开辟4个字节空间(一个int)单个数据
    int* p2 = new int(3);//动态开辟4个字节空间(一个int)并初始化为3
    int* p3 = new int[3];//动态开辟12个字节空间(3个int)的空间

    delete p1;
    delete p2;
    delete[] p3;
}

注意:malloc/free,new/delete,new[]/delete[]一定要匹配使用,不然可能会导致内存泄露。

malloc/free和new/delete的区别和联系

  • 它们都是动态管理内存的入口。
  • malloc/free是C标准库的函数,new/delete是C++的操作符。
  • malloc和free只是动态开辟内存/释放内存的,new/delete不仅开辟空间还调用构造函数和析构函数进行初始化和清理(清理成员)。
  • malloc/free需要手动计算类型大小且返回void*,new/delete可自己计算类型的大小,返回对应类型的指针。
  • malloc失败了返回0,delete失败了抛异常。

    C++的其他内存管理接口:

void* operator new(size_t size); 
void operator delete(size_t size); 
void* operator new[](size_t size); 
void operator delete[](size_t size);

new表达式与operator new函数
标准库函数operator new和operator delete的命名容易让人误解,与其他operator函数不同,这些函数没有重载new和operator表达式,实际上,我们不能重定义new和delete表达式的行为。
总结:

1.operator new/operator delete/operator new[]/operator delete[]和malloc/free用法一样。
2. 他们只负责开辟空间/释放空间,不调构造函数/析构函数来初始化/清理对象。
3. 实际operator new/operator delete是malloc/free的一层封装。
new做了两件事:

  • 调用operator new开辟空间
  • 调用构造函数初始化对象。

    delete也做了两件事:

  • 调用析构函数清理对象。
  • 调用operator delete释放空间

    new[N]

  • 调用operator new分配空间。

  • 调用N次构造函数分别初始化对象。

    delete[N]

  • 调用N次析构函数分别清理对象。
  • 调用operator delete释放空间。

    new/delete,new[]/delete[]系统到底做了什么?

    delete[]的对象是自定义类型时,是怎么知道要调用N次析构函数的?

    这个问题导致我们需要在new[]一个对象数组时,需要保存数组的维度,C++的做法是在分配数组空间时多分配4个字节的大小,专门保存数组的大小,在delete[]时就可以取出这个保存的数,就知道需要调用析构函数多少次了。
    注意:

  • 调用析构函数的次数是从数组对象指针前面的4个字节中取出;

  • 传入operator delete[]函数的参数不是数组对象的指针p,而是p的值减4。

猜你喜欢

转载自blog.csdn.net/qq_40995354/article/details/81224981