new&malloc——CPP

new & malloc

分配区域

通常情况下,new和malloc都是指分配在堆上,也有说new是分配在自由存储区,而malloc则是分配在堆上,自由存储区不一定是堆。

操作系统维护着一个空闲的内存链表,当需要分配内存的时候,就会查找这个表,直到找到一块内存大于所需内存的区域,就分配内存并返回多余内存给链表;

作用机理

new

1
2
string *sp = new string("a value");//分配并初始化一个对象
string *arr = new string[10];//分配10个默认初始化的对象
  • 这里一共执行了3步操作:
    • new调用一个名为operator new/new[]的库函数,该函数分配正确的原始内存来存储对象或对象数组;
    • 编译器运行构造函数初始化对象,并传入初始值;
    • 返回指向该对象的指针;
1
2
delete sp;
delete [] arr;
  • 执行了两步:
    • 执行相应的析构函数;
    • 调用operator delete的库函数,释放内存空间;

如果应用程序希望自定义内存分配,则需要自己定义operator new和operator delete;

malloc

malloc函数是一个库函数,接受一个表示待分配的size_t字节数,返回分配空间的指针,或者NULL表示分配失败。

区别

  • mallco和free是库函数,而new和delete则是操作符;
  • new自己计算所需空间大小,malloc则需要指定大小;
  • new在分配空间之后能进行初始化,malloc只是分配空间并返回指针;

使用

  • malloc
1
2
3
4
5
6
7
8
9
int *a  = (int *)malloc ( sizeof (int ));
if(NULL == a)
{
...
}
else
{
...
}
  • new
1
2
3
4
5
6
7
8
9
int * a = new int();
if(NULL == a) //无意义,因为能走到这步已经以为着分配正常,new在分配失败的时候会抛出异常
{
...
}
else
{
...
}

如果希望new在失败时不是抛出异常,而是返回NULL,可以这样用:

1
2
3
4
5
6
int* p = new(std::nothrow) int;
//或者重载operator new和delete函数
void *operator new(size_t, nothrow_t&) noexcept;
void *operator new[](size_t, nothrow_t&) noexcept;
void *operator delete(size_t, nothrow_t&) noexcept;
void *operator delete[](size_t, nothrow_t&) noexcept;