new和delete

数组和new

 

数组类型变量三个重要限制:

1 数组长度不变

2 在编译时必须知道其长度

3 数组只在定义它的块语句内存在

突破数组的限制

针对2 需要在运行时动态的分配数组

针对3 动态分配的数组一直存在,直到程序显示释放它

 

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

C语言使用一对标准库函数:mallocfree

C++则使用newdelete

 

1 动态数组的定义

int *p = new int [10]; //array of 10 uninitialized ints

返回指向数组第一语速的指针,此返回值初始化了指针 p

 

在自由存储区中创建数组对象是没有名字的,程序员只能通过其地址间接的访问堆中对象

 

2初始化动态分配的数组

string *psa = new string [10];

注意:这里分配了对象的内存空间后,将调用string类型的默认构造函数一次初始化数组中的每个函数

 

int *pia2 = new int [10](); //array of 10 initialized ints

可以在数组长度分配一对空括号,对数组元素做值初始化圆括号要求编译器对数组做值初始化。

i nt *pia2 = new int [10](); 等同于nt *pia2 = new int [10](0);

动态分配的数组全部被初始化为0

 

3 const 对象的动态数组

const int *pci_ok = new const int [100]();

const string *pci = new const string[100];

当然,创建常量元素不予续修改

 

4允许动态分配空数组

原因:编译时不知道数组的长度,编写一下代码:

      size_t n = get _size();

      int  *p = new int [n];

如果get_size 返回 0 ,怎么办?

答案是:代码仍然正确执行

C++虽然不允许定义长度为0的数组,但是明确指明调用new动态创建长度为0 的数组时合法的

char arr[0];//error

int *p = new char [0];

 

5 动态空间的释放

delete[]表示释放指针所指向的数组空间

delete [] pia;

方括号:如果漏了空方括号对,编译器无法发现错误

可导致少释放了内存空间,产生内存泄漏,严重的运行错误等

 

对象和new

 

定义变量时,必须指定其数据类型和名字。而动态创建时,只需指定其数据类型,而不必为该对象命名。

int i ;

int *p = new int;

 

1 动态创建对象的初始化

int i(1024);

int *pi = new int(1024);

 

string s(10,’9’);

string *ps = new string(10, ‘9’);

 

2 动态创建对象的默认初始化

对于类类型的对象,用该类的默认构造函数初始化

string *ps = new string ;

内置类型的对象则无初始化

int *pi = new int ;

 

通常,除了对其复制之外,对未初始化的对象所关联的值的任何使用都没有定义的。

对动态创建的对象做值的初始化

 

string *ps = new string(); //initialized to empty string

int *pi = new int (); //pi points to an int value-initialized to 0;

cls *pc = new cls(); //pc points to a value-initialized of type cls

 

对于提供了默认构造函数的类类型string,没有必要对其对性进行值的初始化:无论程序是明确的不初始化哈市要求进行值初始化,都会自动调用其默认构造函数初始化该对象。

 

3耗尽内存

New失败,系统将抛出名为bad_alloc的一场

 

4 撤销动态创建的对象

delete pi;

 

5 0指针的删除

int *ip = 0

delete ip

删除0指针式安全

 

6 delete之后重设指针的值

执行语句

delete p;后,p变成没有定义。

在很多机器上,尽管p没有定义,蛋仍然存放了它之前所指向对象的地址,然而p所指向的内存已经已经被释放,因此p不再有效。

 

删除指针后,该指针变成悬垂指针。

悬垂指针 :指向曾经存放对象的内存,蛋该对象已经不再存在了。

悬垂指针往往导致程序的错误,而且很难检测出来

 

注意 一旦删除了指针所指向的对象,立即将指针置0,这样就非常清楚的表明指针不再指向任何对象。

 

7 const 对象的动态分配和回收

const int *pci = new const int(1024);

与其他常量一样,动态创建的const对象必须在创建时初始化,并且一经初始化,其值就不能再修改。与其他const对象的地址一样,由于new返回的地址上存放的是const对象,因此该地址只能付给指向const的指针。

 

const string *pcs = new const string ;

 

8 删除const对象

尽管程序员不能够改变const对象的值,但可撤销对象本身。Const对象也是使用删除指针来释放的

delete pci

 

程序错误与动态分配内存分配:

1 删除指向动态分配内存的指针失败,因而无法将该块内存返还给自由存储区,删除动态分配内存失败称为“内存泄漏(memory leak)”。内存泄漏很难发现,等程序运行了一段时间后,耗尽内存空间时,内存泄漏才会显露出来。

 

2 读写已删除的对象。

如果删除指针所指向的对象之后,将指针置为0值,则比较容易检测出这类错误。

 

3 对同一个 呢此存空间使用两次delete表达式。

当两个指针指向同一个动态创建的对象,删除时就会发生错误。如果在其中一个指针上做delete运算,将该对象的内存空间返还给自由存储区,然后接着delete第二个指针,此时则自由存储区可能会被破坏。

 

由C++Primer总结。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值