终于通过测试搞明白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;
}
先看一下代码.
头文件
#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;
}
相关文章推荐
- Jive, 终于快把他的授权及通过代理对论坛的管理弄明白了
- 第一个Hibernate 程序终于测试通过了
- 系统的主要功能终于测试通过了!
- sql2005安装后没有客户端 这个问题困扰好多开发人员!我通过自己的摸索和总结 终于搞明白了!!!
- 交叉编译tslib和qt4.7.3 并在real6410上测试通过。
- Nginx 在centos linux 安装、部署完整步骤并测试通过
- Tuxedo8.1 在 Linux AS4 上基本测试通过
- centos5.4上安装kamailio-3.1.4笔记 测试通过
- lucene结果集的分页处理(百度 分页 方式)终于调试通过了。
- javascript 限制输入和粘贴(IE,firefox测试通过)
- Fckeditor添加导入Word文档功能(已测试通过)
- c测试最后一题(改进:通过定义结构体返回多个值)
- 通过重载new和delete实现简单的对象池
- spring通过profile实现开发和测试环境切换
- 通过logminer分析truncate与delete删除数据的效率问题
- 通过Spark的shell测试Spark的工作
- javascript 限制输入和粘贴(IE和火狐3.x下测试通过)
- malloc/free与c++中new/delete、operator new/operator delete与placement new的区别?
- 为什么不能将ptr_fun(operator delete)传递给For_Each