new / delete 与 malloc / free

int *p = new float[2]; //编译错误(类型安全)
int p = (int)malloc(2 * sizeof(double));//编译无错误

相同点:

  • 都可用于内存的动态申请和释放

不同点:

  • 前者是C++运算符(一般用于生成对象),后者是C/C++语言标准库函数
  • new自动计算要分配的空间大小,malloc需要手工计算
  • new是类型安全的,malloc不是(malloc和free返回的是void类型指针(必须进行类型转换),new和delete返回的是具体类型指针。)
  • new调用名为operator new的标准库函数分配足够空间并调用相关对象的构造函数,delete对指针所指对象运行适当的析构函数;然后通过调用名为operator delete的标准库函数释放该对象所用内存。后者均没有相关调用
  • new是封装了malloc,直接free不会报错,但是这只是释放内存,而不会析构对象
  • malloc仅仅分配内存空间,free仅仅回收空间,不具备调用构造函数和析构函数功能,用malloc分配空间存储类的对象存在风险;new和delete除了分配回收功能外,还会调用构造函数和析构函数
  • new内存分配失败时,会抛出bad_alloc异常。malloc分配内存失败时返回NULL。

new和delete是如何实现的?
new的实现过程是:

  • 首先调用名为operator new的标准库函数,分配足够大的原始为类型化的内存,以保存指定类型的一个对象;
  • 接下来运行该类型的一个构造函数,用指定初始化构造对象;
  • 最后返回指向新分配并构造后的的对象的指针
    delete的实现过程:
  • 对指针指向的对象运行适当的析构函数
  • 简单数据类型默认只是调用free函数;复杂数据类型先调用析构函数再调用operator delete;
  • 然后通过调用名为operator delete的标准库函数释放该对象所用内存
  • 先调用析构函数,再释放内存

delete p、delete [] p、allocator都有什么作用?

  • 动态数组管理new一个数组时,[]中必须是一个整数,但是不一定是常量整数,可以为变量,普通数组必须是一个常量整数;
  • new动态数组返回的并不是数组类型,而是一个元素类型的指针;
  • delete[]时,数组中的元素按逆序的顺序进行销毁
  • new在内存分配上面有一些局限性,new的机制是将内存分配和对象构造组合在一起,同样的,delete也是将对象析构和内存释放组合在一起的。allocator将这两部分分开进行,allocator申请一部分内存,不进行初始化对象,只有当需要的时候才进行初始化操作

被free回收的内存是立即返还给操作系统吗
不会

  • 会首先被ptmalloc使用双链表保存起来,当用户下一次申请内存的时候,会尝试从这些内存中寻找合适的返回,避免了频繁的系统调用
  • 同时ptmalloc也会尝试对小块内存进行合并,避免过多的内存碎片。

malloc申请的存储空间能用delete释放吗?

  • malloc /free的操作对象都是必须明确大小的,而且不能用在动态类上。
  • new 和delete会自动进行类型检查和大小,malloc/free不能执行构造函数与析构函数,所以动态对象它是不行的。

malloc、realloc、calloc的区别

  • malloc函数
void* malloc(unsigned int num_size);
int *p = malloc(20*sizeof(int));申请20个int类型的空间;
  • calloc函数
void* calloc(size_t n,size_t size);
int *p = calloc(20, sizeof(int));
  • malloc申请的空间的值是随机初始化的,calloc申请的空间的值是初始化为0的;
  • realloc函数
void realloc(void *p, size_t new_size);
  • 给动态分配的空间分配额外的空间,用于扩充容量。
posted @ 2023-02-20 11:40  小秦同学在上学  阅读(140)  评论(0编辑  收藏  举报