[置顶] C++primer 4.3 动态数组 、 动态内存分配 new delete

    • 简介
    • 建议
    • 一动态数组的创建和初始化
      • 普通数组的限制
      • 动态数组与普通数组的区别
      • 动态数组定义
      • 初始化动态分配的数组
        • 1 标准库类型和内置类型初始化值的区别
      • const 对象的动态数组
      • 允许动态分配空数组
      • 动态空间的释放
    • 二动态数组的使用

简介

  • 每一个程序在执行时都占用一块可用的内存空间,用于存放动态分配的对象,此存空间称为程序的自由存储区或堆**

  • 当你定义一个动态数组时,就已经给你分配了内存空间,如果你只是定义却没有初始化,那么内存空间里面的元素可能没有默认初始化,比如内置类型的动态数组

  • c++语言使用new和delete表达式实现动态内存分配,在C语言中使用的是malloc 和free 函数;

  • 要想实现初始化可以在最后面加上一对圆括号 int *pia2=new [ 10 ] ( )

  • const 对象的动态数组必须初始化

  • 动态数组用完,必须显示释放其占用的内存

  • 使用delete 表达式释放指针所指向的数组空间 delete [ ] pia

建议

======================================================================================================================

一、动态数组的创建和初始化

1.普通数组的限制

  1. 数组长度固定;
  2. 编译时必须知道其长度;
  3. 数组只能在定义它的块语句内存在。

因为在实际过程中不能忍受这样的限制,他们需要在运行时动态分配数组。

2.动态数组与普通数组的区别

  1. 虽然数组长度固定,但动态分配的数组不必在编译时知道其长度,可以在运行时才确定数组长度;
  2. 动态数组将一直存在,直到程序显示释放它为止。

3.动态数组定义

  1. 每一个程序在执行时都占用一块可用的内存空间,用于存放动态分配的对象,此内存空间称为程序的自由存储区free store或堆heap
  2. c++语言使用new 和delete表达式实现动态内存分配,在C语言中使用的是malloc 和free 函数;
  3. 动态分配数组时,只需指定类型和数组长度,不需要为数组对象命名,new 表达式返回指向新分配数组的第一个元素的指针
    int * pia = new int[10];
    new 表达式分配了一个含有10个int型元素的数组,并返回指向数组第一个元素的指针,该返回值初始化了指针pia.
  4. new 表达式需要指定类型以及在方括号中给出的数组维数,该维数可以是任意的表达式。
  5. 在自由存储区内创建的数组对象是没有名字的

4.初始化动态分配的数组

  • 定义动态数组之后可以不显示初始化

  • 动态分配数组时,如果数组元素具有类类型,将使用该类的默认构造函数实现初始化;

  • 如果数组元素是内置类型,则无初始化,但是都是分配了内存空间的

    4.1 标准库类型和内置类型初始化值的区别

//1.标准库类型和内置类型动态数组默认的初始化


string *psa=new string[10];// 10个空的string
int *pia=new int[10];//10个没有初始化的元素
int *pia2=new[10]();//加上圆括号之后就会要求编译器对数组做值初始化,在本例中把元素都设置为0.

//这两个new表达式都分配了含有10个对象的数组,其中第一个数组是string类型,分配了保存对象的内存空间后,将调用string类型的默认构造函数依次初始化数组中的每个元素。

//第二个数组则具有内置类型的元素,分配了存储10个int对象的内存空间,但是都没有初始化。

//加上圆括号之后就会要求编译器对数组做值初始化,在本例中把元素都设置为0.
//2.标准类型数组和内置类型数组默认的初始化


string sa[10];//自动调用string类默认构造函数,各元素初始化为空字符串
int ia[10];   //ia 在函数体外定义的内置数组,各元素初始化为0
int main()
{
string  sa2[10];//自动调用string类默认构造函数,各元素初始化为空字符串
int ia2[10];//ia 在函数体内定义的内置数组,各元素未初始化,值不确定
}
//3.标准库类型和内置类型变量的默认初始化

int global_int;   //在函数体外定义的内置数据类型,默认初始化为0;
string global_s;        //函数体外定义的标准库类型,默认初始化为空串
int main(){
int local_int;    //在函数体内定义的内置数据类型,没有进行初始化,变量值未确定;
string local_s;       //在函数体内定义的内置数据类型,默认初始化为空串;
return 0;
}

5.const 对象的动态数组

  • 如果我们在自由存储区中创建的数组存储了内置类型的const对象,则必须为这个数组提供初始化。
  • 因为数组元素都是const对象,无法赋值,所以必须初始化。
const int * pci_bad = new const int[100];//错误,必须初始化
const int *pci_bad = new const int[100]();//正确,初始化了
const string *pcs =new const string[100];//默认初始化

6.允许动态分配空数组

size_t n=get_size();
int *p=new int [n];//创建动态数组
for(int *q=p;q!=p+n;++q)

7.动态空间的释放

  • 动态分配的内存最后必须进行释放,否则,内存最终将会逐渐耗尽;
  • 如果不再需要使用动态数组,程序员必须显示将其占用的存储空间返回给程序的自由存储区;
  • 使用delete 表达式释放指针所指向的数组空间 delete[ ] pia
    • 该语句回收了pia所指的数组,把相应的内存返回给自由存储区;
    • [ ] 是必不可少的,因为它告诉编译器该指针指向的是自由存储区中的数组,而不是当对象

二、动态数组的使用

你可能感兴趣的:(动态数组,malloc,delete,new,动态内存)