天天看点

C++的动态内存分配

C

语言的

malloc

,

calloc

,

realloc

free

函数对应,

C++

语言使用

new

delete

运算符实现动态内存分配和释放。

使用new运算符动态分配内存

new

运算符分配内存分为以下两类情境:一是为变量动态分配内存,而是为数组动态分配内存。其中为变量动态分配内存的一般形式为:

T* p = new T(...);
           

T

是任意类型名,赋值运算符右边的

T

后可以跟括号,括号内是初始化该变量的值或该类的某一个构造函数的参数列表。程序执行到这里,在堆中动态分配出一块

sizeof(T)

大小的内存空间,

p

中存放着这段内存空间的起始地址。为数组动态分配内存的一般形式为:

T* p = new T[N];
           

T

是任意类型名,

N

为数组元素的个数,可以是整型表达式。若T是类,则利用

T

的默认构造函数进行初始化。程序执行到这里,在堆中动态分配一块

N*sizeof(T)

大小的内存空间,

p

中存放着这段内存空间的地址。

delete

运算符释放动态分配的内存

new

运算符分配的内存空间不会在程序离开其所发挥作用的程序块时自动释放内存空间,而只能在程序退出时才能得到释放。因此必须使用

delete

运算符显式地释放动态分配的内存空间。对于为变量分配的内存空间,则直接使用

delete p;

进行释放,而对于为数组分配的内存空间,则需要使用

delete [] p;

进行释放。在程序中,要保证使用了一个

new

运算符,就有且仅有一个

delete

运算符与之对应。

小心:除了保证new和delete的成对出现,还要保证两者的形式相同,若用new ..[]为数组分配内存空间,必须用delete []释放该内存空间,若用new为变量分配内存空间,必须用delete释放该内存空间,否则会产生难以预料的结果。使用typedef将数组定义为其他名称大大增加了出现这种错误的可能,因此因避免这种情况。

/*****************************************
 * memory_alloc.cpp                      *
 *                                       *
 * C++的动态内存分配                     *
 *****************************************/

#include <iostream>
using namespace std;

class A
{
private:
  int index;
  static int id;
public:
  A()
  {
    index = id;
    cout<<"构造函数(id = "<<index<<")被调用"<<endl;
    id++;
  }
  ~A()
  {
    cout<<"析构函数(id = "<<index<<")被调用"<<endl;
  }
};

int A::id = ;

int main()
{
  int *p = new int;
  cout<<"*p = "<<*p<<endl;
  delete p;
  int *p1 = new int();
  cout<<"*p1 = "<<*p1<<endl;
  delete p1;
  A *p2 = new A;
  delete p2;
  A *p3 = new A[];
  delete [] p3;

  return ;
}
           
C++的动态内存分配

参考文献

  1. https://www.coursera.org/course/pkupop
  2. Scott Meyers著,侯捷译. Effective C++中文版. 电子工业出版社. 2012.

继续阅读