C/C++教程

C++学习---动态内存

本文主要是介绍C++学习---动态内存,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

学习线性表的过程中,知道了线性表的两种实现方式,一种是静态的一种是动态的,动态线性表的实现中经常可以看到分配空间的语句L = new Lnode,在释放的时候是delete L。虽然这样用,但是一直不知道为什么要这样用。

  • 在C++中,动态内存管理是通过一对运算符来完成的,分别是new与delete。
  • new:在动态内存中作为对象分配空间并返回一个指向该对象的指针
  • delete:接受一个动态对象的指针,销毁该对象,释放与之关联的内存。
  • 缺点:使用动态内存很容易出问题,因为确保在正确的时间内释放内存是极其困难的。有时候会忘记释放内存,容易产生内存泄漏;还有在有其他指针引用内存的情况下我们就释放了它,这时会产生引用非法内存的指针。
  • 为了解决上面的问题,C++标准库中提供了两种智能指针,可以复负责自动释放所指向的对象。分别为shared_pt和unique_ptr,还有一个weak_ptr的伴随类。这里简单了解,不在细说,具体等深入学习后在更新。
int *pia = new int[get_size];  //pia指向第一个int,调用get_size确定分配多少个int
//方括号内必须为整型,但不必是常量

//使用类型别名来分配数组
typedef int arrT[42];  //arrT表示42个int的数组类型
int *p = new arrT;     //分配一个42个int的数组,p指向第一个int;

上述new分配了一个int数组,并返回指向第一个int的指针
注意:即使代码中没有方括号,但是编译器执行这个表达式的时候还是会用到new[],即编译器实际执行的时候是:
int *p = new int[42];

  • 分配一个数组会得到一个元素类型的指针

    • 但使用new分配一个数组的时,我们并未得到一个数组类型的对象,而是得到一个数组元素类型的指针。即使我们使用类别定义了一个数组类型,new也不会分配一个数组类型的对象。new返回的是一个元素类型的指针。
  • 初始化动态内存分配对象的数组

    • 默认情况下,new分配的对象,不管是单个分配的还是数组中的,都是默认初始化的。对一个数组中的元素进行值初始化,方法是在大小之后跟一对空括号
      int *pia = new int[10]; //10个未初始化的int
      int *pia2 = new int[10](); //10个值初始化为0的int
      int *pia3 = new int[10]{1,2,3,4,5,6,7,8,9,0}; //10个int分别用类别中对应的初始化器进行初始化
    • 初始化器会用来初始化动态数组中开始部分的元素,如果初始化器数目小于元素数目,剩余元素将进行值初始化。如果初始化器数目大于元素数目,则new表达式失败,不会分配任何内存
  • 假设分配的大小为int *p = new int[0],new会返回一个合法的非空指针。该指针与new返回的其他任何指针都不相同,可以向此指针加上或减去0,也可以从此指针减去自身得到0。但是,此指针不能解引用,因为它不指向任何元素

释放动态内存

delete p;  //p必须指向一个动态分配的对象或为空;
delete []pa;  //pa必须指向一个动态分配的数值或为空;
  • 第二条语句销毁pa指向的数组中的元素,并释放对应的内存,数组中的元素按照逆序销毁。也就是最后一个元素最先销毁,然后是倒数第二个,以此内推。
  • 当释放一个指向数组的指针的时候,空方括号是必需的。它指示编译器此指针指向一个对象数组的第一个元素。
  • 如果在delete一个指向数组的指针时未加上[],或者在对一个非数组的对象上加上[],这样的行为是未定义的,即是未知的。
    这个时候,程序编译的时候不会出错,但我们的程序可能在执行过程中在没有任何警告的情况下行为异常。
这篇关于C++学习---动态内存的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!