c++动态分配

一、 new/new[]的使用

new的四种使用方法:
1.  MyClass * p1 =  new MyClass;
     分配一个对象,内存若不够则发出bad_alloc异常。 如果异常没有被catch捕获, 则程序中止。

     内部原理,new分为两个执行步骤:1. 调用 void* operator new (std::size_t size);2. 调用对象的构造函数。

     使用举例1:
  try
  {
    int* myarray= new int[10000];
  }
  catch (std::bad_alloc& ba)
  {
    std::cerr << "bad_alloc caught: " << ba.what() << '\n';
  }
     使用举例2:
   int* myarray= new int[10000];

   //说明:在内存不足的时候,new会发异常。由于异常没有被catch捕获,则将会中断程序的执行。由于内存不够引起的错误将会发出异常,因此此处不需对myarray进行判0比较。

2.  MyClass * p2 =  new (std::nothrow) MyClass; 
    分配一个对象,内存不够则返回空指针。
     
     内部原理,分两个步骤:
              1. 调用 void* operator new (std::size_t size, const std::nothrow_t& nothrow_value) noexcept;
              2. 调用对象的构造函数。
     使用举例:
  char* p = new (std::nothrow) char [1048576];

  if (p==0) std::cout << "Failed!\n";

3.  new (p2) MyClass;
      不分配空间,调用p2的构造函数,MyClass 表示p2指针所指类型,并返回p2指针。
     
     内部原理, 分为两个步骤:
             1. 调用 void* operator new (std::size_t size, void* ptr) noexcept;
             2. 调用指针对应的构造函数。

4. MyClass * p3 = (MyClass*) :: operator  new ( sizeof(MyClass));
     仅分配空间,不调用构造函数。

new[]用于数组的动态分配,类似的四种使用方法为:
1.   MyClass * p1 =  new MyClass[5];
2.   MyClass * p2 =  new (std::nothrow) MyClass[5];
3.   MyClass * p3 =  static_cast<MyClass*> (:: operator  new ( sizeof(MyClass[5])));
4.    new (p3) MyClass[5];

参考文献:


二、 c++ 内存分配 new 和 allocator

关于内存的分配,有两种方式:采用操作符new 或者使用类 allocator。

使用方法
两者典型的使用方法如下(其中typename泛指类型名字;typepoint泛指指向该类型的指针):
typepoint = new typename;
如 string *p = new string;

std::allocator<typename> alloc;
typepoint = alloc.allocator(num);
如 std::allocator<string> alloc;
     string *p = alloc.allocator(1);

不同
两者最大的不同是,对于new而言,在分配一块内存空间的时候,还会调用构造函数,如上例子,将会调用string的构造函数;但是,对于allocator而言,仅仅负责分配一块空间,不会调用构造函数。

适用范围
对于一般应用的时候,通常采用new。
在STL中,而是采用allocator来分配内存。

原理分析
已知:
string *sp = new string("a value");
对于new, 基于上面例子此时实际进行了三步操作:1. 调用库函数 operator new (或者 operator new[])分配原始,没有类型属性的内存空间;2. 编译器调用合适的构造函数用于初始化;3. 最后返回指向分配空间的指针。

对于alloc.allocator内部仅调用了operator new函数。

三、 new 和 delete 的重载
    
     在头文件new中,定义了8个重载的operator new 和 delete函数, 其中前四个对应的new 在分配失败的时候会发出bad_alloc异常.后四个对应的new,在分配失败的时候会返回空指针,不会发出异常。
// these versions might throw an exception
void *operator new(size_t);  // allocate an object
void *operator new[](size_t);  // allocate an array
void *operator delete(void*) noexcept;  // free an object
void *operator delete[](void*) noexcept; // free an array

// versions that promise not to throw; 
void *operator new(size_t, nothrow_t&) noexcept;
void *operator new[](size_t, nothrow_t&) noexcept;
void *operator delete(void*, nothrow_t&) noexcept;
void *operator delete[](void*, nothrow_t&) noexcept;

四、 malloc/free 和 new/delete 的区别

 1. malloc/free 为函数, 而 new/delete为运算符;
 2. malloc/free仅仅分配、释放空间; 而new 由两个步骤组成:分配空间(operater new)和调用构造函数(constructor);delete先调用析构函数(destructor)然后释放空间(operator delete);
 3. new是类型安全的,而malloc不是。
     举例1:不需要强制转换
          int *p1 = (int*)malloc(sizeof(int) * length);
          int *p2 = new int[length];
     举例2:
          int *p = new float[2];
          int *p= malloc(2*sizeof(float));
     
 4. 在内存不足的时候,malloc返回空指针;而new 发出bad_alloc异常, 在nothrow修饰的时候返回空指针。

参考文献



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值