您的位置:首页 > 其它

new和delete的使用规范

2015-10-30 15:37 197 查看
C++的动态内存管理是通过new和delete两个操作来完成的,即用new来申请空间,用delete来释放空间。在使用new和delete时,注意以下原则。

(1)程序运行时,new操作和delete操作必须一一对应。

用new操作申请空间,如果申请成功,必须在以后的某个时刻用delete释放该空间,既不能忘记释放,也不能多次释放。前者会引起内存泄露,后者会引起运行时错误。如下面的程序。

#include <iostream>
using namespace std;

int main(){
int *p;
p=new int(3);
if(p)
delete p;
delete p;
return 0;
}


以上程序对指针p所指向的空间进行两次释放,这种内存错误对C/C++的程序危害极大,也是很多人对C++语言忘而却步甚至的原因。多次释放同一块内存空见,并不一定立即引起程序运行错误,也不一定会导致程序运行的崩溃,这跟具体的编译器实现有关。但是,多次释放同一块内存空间绝对是一个编程错误,这个编程错误可能会在其后的某个时刻导致其他的逻辑错误的发生,从而给程序的调试和纠错带来困难。考察如下程序。

#include <iostream>
using namespace std;

int main(){
int *p,*q,*one;
one=new int;
if(one)
cout<<one<<endl;
delete one;
p=new int(3);
if(p)
cout<<p<<endl;
delete one;//假设这句语句是程序员不小心加上的
q=new int(5);
if(q)
cout<<q<<endl;
cout<<(*p)+(*q)<<endl;
delete p;
delete q;
}


程序通过编译并运行结果:

003289A0

003289A0

003289A0

10

程序运行过程中会产生中断。从程序的输出可以看出,在将指针one所指向的空间释放后,为指针p申请的空间就是原来one所指向的空间。由于不小心在为p分配空间之后再次使用了delete one,导致q申请到的空间就是原来p所申请的空间,这样赋给*q的值就改写了原来p所指向的单元的值,导致最后输出结果为10。

由此可知,多次释放同一块内存空间,即使不导致程序运行中断,也会破坏环境,使指针与所对应的空间的隶属关系出现混乱,从而导致逻辑错误。在大型程序设计中,这种逻辑错误的查找会变得十分费时费力。

注意:当指针p的值为NULL时,多次使用delete p并不会带来麻烦,因为释放空指针的空间实际上不会导致任何操作。所以,将“不用”的指针设置为NULL是一个好的编程习惯。

(2)当类的成员中有指针变量时,在构造函数中用new申请空间并且在析构函数中用delete释放空间是一种“标准的”、安全的做法。

例如下面的程序。

#include <iostream>
using namespace std;

class Student{
char* name;
public:
Student(){
cout<<"Default constructor"<<endl;
}

Student(char*);
~Student();
};

Student::Student(char*s){
//Student();//此句运行时报错,构造函数不能调用其他构造函数
cout<<"In constructor,allocating space"<<endl;
name=new char[strlen(s)+1];
strcpy(name,s);
cout<<"name:"<<name<<endl;
}

Student::~Student(){
cout<<"In destructor, free space"<<endl;
delete name;
}

int main(){
Student s1("张三");
}


程序运行输出:

In constructor,allocating space

name:张三

In destructor, free space

由于任何一个对象,其构造函数值调用一次,其析构函数也值调用一次,这样就嫩巩固保证运行时new和delete操作是一一对应的,也就是保证了内存管理的安全性。

在C++语言中,一个构造函数不能调用本类的另一个构造函数,其原因就是为了防止构造函数的相互调用打破了内存申请与释放之间的这种对应关系。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: