blueyi's notes

Follow Excellence,Success will chase you!

0%

C/C++拾遗之new/delete与malloc/free的异同

SOF上一个比较全面的回答:http://stackoverflow.com/questions/240212/what-is-the-difference-between-new-delete-and-malloc-free
根据理解举例总结如下:
共同点就是都可以用于分配和销毁动态内存。
不同点:
默认是指new/delete :

  1. 在空内存池(Free Store)上分配内存空间,而malloc是在堆上分配,关于free-store和heap的区别可以看这里, 下面会对内存区域详解。http://stackoverflow.com/questions/1350819/c-free-store-vs-heap
  1. new返回一个类型安全的指针,即该指针有明确的类型,而malloc返回的是个void *,所以需要将其强制转换为所需要的指针。即new相当于在动态内存上创建一个新对象,并调用该对象的默认构造函数初始化该对象,而malloc就单纯是分配一块原始内存
  2. new在失败时会抛出异常std::bad_alloc,而malloc在分配失败时返回NULL
  3. new可以根据类型自动计算所需要分配的空间大小,而malloc必须手动指定需要分配的空间字节数
  4. new可以直接处理数组,例如int *p = new int[4];,而malloc需要手动确定大小。int *p = (int *) malloc(4 * sizeof(int));,但要记得使用delete[]来释放使用new分配的数组。
  5. 需要对已分配的内存扩容时,malloc分配的可以调用realloc高效的直接分配一块更大的内存。但由于new分配的其实相当于是对象,由于拷贝构造函数的问题,所以无法直接简单地扩展其内存。
  6. new/delete的实现其实就是调用malloc和free
  7. 可以通过设置std::set_new_handler来控制new/operator new在分配内存失败是调用处理函数new_handler来补救,而malloc不能
  8. new/delete是操作符,所以可以被重载,而malloc/free是函数,无法被覆盖
  9. new/delete在分配内存后会调用相应的构造函数初始化已经分配的内存/析构函数释放内存,而malloc分配的就是原始内存

总结来说就是:new/delete是操作符而malloc/free是两个函数,new/delete会调用构造函数和析构函数,可以被类重载,且new是类型安全的,一般情况下尽量避免使用malloc/free而使用new/delete。
另外注意delete或free只是释放相应的内存,并不会修改原指针变量,所以如有需要依然可以让原指针变量指向其他地址,如下例

operator new和operator new[]是两个操作符,同样operator delete和oprator delete[]也是两个操作符。

sizeof运算符作用于指针时不能像作用于数组那样获得整个数组的大小,sizeof作用于指针时只能获取指针本身的大小,例如32位系统是4个字节,64位系统是8个字节

使用operator new(size)operator delete(p)也可以用于一次开辟一段指定大小的原始内存,类似malloc的功能,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
//malloc和free在该头文件中
#include <cstdlib>
//operator new和operator delete在该头文件中
#include <new>

int* assign(int *p, int n)
{
for (int i = 0; i < n; ++i) {
p[i] = i;
}
return p;
}
void print(int *p, int n)
{
for (int i = 0; i < n; ++i) {
std::cout << p[i] << " ";
}
std::cout << std::endl;
}

int main(void)
{
//使用new和malloc使用三种方式实现动态数组
//使用operator new操作符先分配一段原始内存,再强制转换为所需要的内存
void *p = operator new(5 * sizeof(int));
int *p1 = static_cast<int *>(p);
assign(p1, 5);
print(p1, 5);
operator delete (p); //或 delete p1;

//使用new操作符直接声明数组
//注意此处依然使用p1
p1 = new int[5];
assign(p1, 5);
print(p1, 5);
delete[] p1;

//使用malloc函数
p1 = (int *)malloc(5 * sizeof(int));
assign(p1, 5);
print(p1, 5);
free(p1);

return 0;
}

Welcome to my other publishing channels