您的位置:首页 > 运维架构

终于通过测试搞明白operator delete了!

2007-07-06 21:14 495 查看
最近写了一个简单的学生管理系统的类 在内存管理的地方遇到了点麻烦,现在解决了,对operator delete有了更深入的了解!

先看一下代码.

头文件

#ifndef KEXIN
#define KEXIN

#include <iostream>
#include <new>

#endif

namespace mystd
{
class cstudent
{
private:
char * pname;
int age;
char * which_one_class;
int number_of_class; //学号
char * paddress;
public:
cstudent(char * ="",int =0, char * ="", int =0,char * ="");

cstudent(const cstudent &);

cstudent & operator=(const cstudent &);

~cstudent(void)
{

};

friend std::ostream & operator<<(std::ostream & , const cstudent &);
friend std::istream & operator>>(std::istream & , cstudent &);

char * get_name() const;
int get_age() const;
char * get_class() const;
int get_number_of_class() const;
char * get_address() const;

bool reset(char * ="",int =0, char * ="", int =0,char * ="");

};

class cclass
{
private:
cstudent * pstudent;
cstudent monitor;
char * class_number;
int m_space;
int use;
cclass & operator=(const & cclass);
cclass(const & cclass);
public:
cclass(char * ,int ,const cstudent &);

bool is_this_class(const cstudent &) const;
bool add_student(const cstudent &);
int get_use() const;
int get_space() const;
cstudent & get_monitor();
bool resize(char * ,int , const cstudent & );

};
}

CPP文件

#include "cstudent.h"
namespace mystd
{
cstudent ::cstudent(char * a ,int b, char * c, int d,char * e)
{
pname=a;
age=b;
which_one_class=c;
number_of_class=d;
paddress=e;
}

cstudent ::cstudent (const cstudent & an):pname(an.pname) , age(an.age) ,which_one_class(an.which_one_class),
number_of_class(an.number_of_class) , paddress(an.paddress) {/*empty funtion*/}

cstudent & cstudent ::operator=(const cstudent & x)
{
pname=x.pname;
age=x.age;
which_one_class=x.which_one_class;
number_of_class=x.number_of_class;
paddress=x.paddress;
return *this;
}

char * cstudent::get_name() const
{
return pname;
}

int cstudent::get_age() const
{
return age;
}

char * cstudent::get_class() const
{
return which_one_class;
}

int cstudent::get_number_of_class() const
{
return number_of_class;
}

char * cstudent::get_address() const
{
return paddress;
}

std::ostream & operator<<(std::ostream & out , const cstudent & object)
{
out<<object.pname<<std::endl
<<object.age<<std::endl
<<object.which_one_class<<std::endl
<<object.number_of_class<<std::endl
<<object.paddress<<std::endl;
return out;
}

std::istream & operator>>(std::istream & in ,cstudent & objecttwo)
{
std::cout<<"please put in name with this student!"<<std::endl;
in>> objecttwo.pname;
std::cout<<"please put in age with this student!"<<std::endl;
in>> objecttwo.age;
std::cout<<"please put in which one class of this student!"<<std::endl;
in>> objecttwo.which_one_class;
std::cout<<"please put in which number of class of this student!"<<std::ends<<'/n';
in>> objecttwo.number_of_class;
std::cout<<"please put in address of this student!"<<std::endl;
in>> objecttwo.paddress;
return in;
}

bool cstudent::reset(char * aa , int bb , char * cc , int dd , char * ee)
{
if (aa=="" && bb==0 && cc=="" && dd==0 && ee=="")
{
std::cout<<"please take five count with this funtion run!" << std::endl;
return false;
}

pname=aa;
age=bb;
which_one_class=cc;
number_of_class=dd;
paddress=ee;

return true;
}

cclass :: cclass (char * a_a,int b_b,const cstudent & c_c): class_number(a_a),
pstudent(static_cast<cstudent *> (operator new( sizeof(cstudent)*b_b) ) ), monitor(c_c), m_space(b_b)
{
use=0;
}

bool cclass :: is_this_class(const cstudent & theone) const
{
return ( class_number==theone.get_class() );
}

bool cclass :: add_student(const cstudent & theother)
{
if( use == m_space )
{
std::cout<<"sorry,no space store this student!"<<std::endl;
return false;
}

cstudent * old= pstudent;

for (int m=0; m<use ; m++)
{

++old;
}

new (old) cstudent( theother );

++use;

return true;

}

int cclass :: get_use() const
{
return use;
}

int cclass :: get_space() const
{
return m_space;
}

cstudent & cclass::get_monitor ()
{
return monitor;
}

bool cclass::resize(char * one , int two , const cstudent & three)
{
if (two<m_space)
{
std::cout<<"please give more space!"<<std::endl;
return false;
}
if (one!=class_number)
{
std::cout<<"the class number is error!"<<std::endl;
return false;
}
if (monitor.get_name() != three.get_name())
{
std::cout<<"the monitor is not same"<<std::endl;
std::cout<<"Do you decide to continue?"<<std::endl;
std::cout<<"yes // no ?"<<std::endl;

char yn;
std::cin>>yn;

if (yn != 'y')
{
std::cout<<"you decide to no!"<<std::endl;
return false;
}

std::cout<<"the monitor will be reset!"<<std::endl;
}

cstudent * olddel=pstudent;

for (int bb=0;bb<use;bb++)
{
olddel->~cstudent();
++olddel;
}

operator delete(pstudent);

pstudent= static_cast<cstudent *> (operator new( sizeof(cstudent)*two) );

monitor=three;

m_space=two;

return true;
}

}

通过高手的指点,和自己的测试,终于明白OPERATOR DELETE ()的使用方法了.
使我确定VC中NEW.H是不提供 OPERATOR DELETE[]的.
既然是成对使用,那编译器 或者 操作系统就一定在NEW是 对该指针申请的内存数量是知道的,即使是OPERATOR NEW 一个类型数组,在OPERATOR DELETE ()时只删除一次这个指针就可以了,因为操作系统在NEW时知道内存数量,所以之前把OPERATOR DELETE ()放在FOR 循环里是不对的.因为指针加后的内存已经被一次性释放了.

下面是我的测试程序 来证明一次性确实释放了整个数组占用的内存.

operator delete(pstudent);

std::cout<<pstudent->get_name();

或者

operator delete(pstudent);
std::cout<< (++pstudent) -> get_name();

都是不对的.++pstudent 在调用get_name()就是想知道删除PSTUDENT指针是不是把相临的几块同大小内存都删除了,结果是上边所说的那样的.

所以正确的代码应该是
cstudent * olddel=pstudent;
for (int bb=0;bb<use;bb++)
{
olddel->~cstudent();
++olddel;
}

operator delete(pstudent);

先析构内存中的对象,在释放内存.

关于新加的这段内存管理代码如下:

bool cclass::resize(char * one , int two , const cstudent & three)
{
if (two<m_space)
{
std::cout<<"please give more space!"<<std::endl;
return false;
}
if (one!=class_number)
{
std::cout<<"the class number is error!"<<std::endl;
return false;
}
if (monitor.get_name() != three.get_name())
{
std::cout<<"the monitor is not same"<<std::endl;
std::cout<<"Do you decide to continue?"<<std::endl;
std::cout<<"yes // no ?"<<std::endl;
char yn;
std::cin>>yn;
if (yn != 'y')
{
std::cout<<"you decide to no!"<<std::endl;
return false;
}
std::cout<<"the monitor will be reset!"<<std::endl;
}

cstudent * olddel=pstudent;
for (int bb=0;bb<use;bb++)
{
olddel->~cstudent();
++olddel;
}

operator delete(pstudent);

pstudent= static_cast<cstudent *> (operator new( sizeof(cstudent)*two) );
m;
m_space=two;
return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: