那位高手来帮忙详细解释重载new[]与delete[]的问题

sjzxywzf 2008-05-28 05:39:51
我看到重载new[]与delete【】里边有个例子特别复杂,谁能帮我解释以他的用法
...全文
131 点赞 收藏 5
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
na_he 2008-05-30
但是要注意匹配哦,如果new的是一个数组对象,既要用delete[]而不是delete
回复
RocCheung 2008-05-30
new动态创建.
delete删除你动态创建的空间.
就这么理解就可以了.
回复
hyram 2008-05-28
学习
回复
这里有一篇全英文的
http://blog.csdn.net/fz_zhou/archive/2007/06/05/1639867.aspx
回复
k2eats 2008-05-28
动态创建对象(new & delete)在C++中是一个功能强大的东西.它既带来好处,也带来一定的烦恼.
如果使用不当,后果难想啊~~
由于程序中的需要,C++也赋予它像其它操作符一样可以重载.


1).热身运动
必备知识:当创建一个new时有两件事发生.首先,使用运算符new分配内存,然后调用构造
函数。而delete,先调用析构函数,然后使用运算符delete释放内存。

2).重载全局NEW & DELETE
例子:
#include
#include

void* operator new(size_t s) /*size_t是由编译器给的,NEW返回一个void*来分配空间.(size_t是否就是一个long类型呢?)*/
{
void* mem = malloc(s);
//由于是重载的NEW & DELETE是全局,所以用malloc & free来分配和注销空间
if (!mem) puts("out");
//不能使用iostream是因为它用到new & delete,会进入死锁状态.
return mem;
}

void operator delete(void* mem)
{
free(mem);
}

int main()
{
int* test1 = new int(10);
int* test2 = new int[5];
/*能分配数组对象,在所有情况里,都是使用全局重载版本的new和delete。和下面重载一个类的new&delete有所不同.*/
delete test1;
delete []test2;
return 0;
}

3).为一个类重载new和delete
例子:
#include
#include

class test
{
public:
test()
{
cout<<"test()"< }
~test(){cout<<"~test()"< void* operator new (size_t) //返回一个void*来分配空间
{
for (int i=0;i if (!nt[i]) //查找是否有足够空间
{
nt[i]=1; //做标记,表明此空间被使用.
cout<<"new....."< return mem+(i*sizeof(test));
/*因为一个类所需的空间比较大,所以用sizeof(test)得出这类需要的空间.
从另一个角度来看,mem+(i*sizeof(test))算是一个"逻辑位置".而mem[n]才算"物理位置".*/
}
//return 0; //这里应该调用NEW异常
cout<<"out of memory"< }
///////////////////////////
void* operator new[] (size_t) //重载new & delete的数组版里的内容和一般版的一样.
{
for (int i=0;i if (!nt[i]) //查找是否有足够空间
{
nt[i]=1;
cout<<"new[]....."< return mem+(i*sizeof(test));
}
cout<<"out of memory"< }
////////////////////////////////
void operator delete (void *m)
{
if (!m) return;
unsigned long block =(unsigned long)m - (unsigned long)mem;
block /=sizeof(test);
nt[block] = 0;
cout<<"delete....."< }
///////////////////////////////////
void operator delete[] (void *m)
{
if (!m) return;
unsigned long block =(unsigned long)m - (unsigned long)mem;
block /=sizeof(test);
nt[block] = 0;
cout<<"delete[]....."< }
private:
static unsigned char mem[]; //空间地址分配区
static unsigned char nt[]; //一个nt[1]代表一个区,1表示这区已经被利用,0表示空的区
enum{ss=100}; //空间分配区的大小
};

unsigned char test::mem[ss*sizeof(test)]; //由于是为一个类重载的,所以sizeof(test)
unsigned char test::nt[ss]={0};

int main()
{
test *a = new test;
cout<<"new ok"< test *b = new test[5];
/*!!!要注意,如果在类里没有重载new & delete的数组版,
那当new 或 delete 这个类的数组时,系统会使用全局
的new & delete的版本,除非在类里重载new & delete的数组版.
和全局重载的不同,因为你所重载的是用户自定义类型.
*/
cout<<"new []ok"< delete []b;
cout<<"delete []ok"< delete a;
cout<<"delete ok"< system("pause");
return 0;
}

大家可能注意到.为一个类重载new&delete这例子中没有用到malloc/new这些分配空间函数.
是因为这例子中所分配空间的位置是在mem[]中,它是一个static unsigned char 的类型,已在
系统已经为它在堆里分配好空间了.如果你想使用new&delete来重载一个类的new&delete也是可以的,
如:
class test2
{
public:
void* operator new(size_t s)
{
return ::new char[s]; //因为这里要用全局的new,所以要用::符号.
} //我觉得这种方式在管理空间方面不如上面这个例子.当然,可以适当去使用自己的内存管理方案.

void operator delete(void* mem)
{
delete ::[]mem;
}
};
......
回复
相关推荐
发帖
新手乐园
创建于2007-09-28

3.3w+

社区成员

C/C++ 新手乐园
申请成为版主
帖子事件
创建了帖子
2008-05-28 05:39
社区公告
暂无公告