为什么重载的delete运算符未被vector调用?

tangtao 2001-04-23 02:39:00
加精
下面是我写的为试验重载new、delete 运算符写的一个小程序

可是从输出的结果看,delete运算符在vector中却一直未被调用,可程序最后一行却显示delete可以运行,这是为什么?请各位大虾帮忙!

运行环境:
rh 6.2
kernel 2.4
gcc 2.95.3
stlport 4.0

//-------------------------------------------------------
// Example test new & delete operator
//
#include <iostream>
#include <vector>
#include <cstddef>
#include <new>

using namespace std;

class Packet
{
public:

static const int BUFF_SIZE = 2048;
static const int BUFF_NUM = 100;

Packet(){}
Packet(const Packet& r){ memmove(_buff,r._buff,BUFF_SIZE); }
~Packet() {}

const char* getbuff() const {return _buff;}
void setbuff(char* r){ memmove(_buff,r,BUFF_SIZE); }


void operator=(const Packet& r) { memmove(_buff,r._buff,BUFF_SIZE); }
static void* operator new(size_t) throw(bad_alloc);
static void* operator new(size_t,Packet* &addr) throw(bad_alloc);
static void operator delete(void*) throw();

private:

char _buff[BUFF_SIZE];

static char pool[];
static bool pool_idx[];

static int _num;

};

char Packet::pool[Packet::BUFF_NUM * sizeof(Packet)];
bool Packet::pool_idx[Packet::BUFF_NUM];
int Packet::_num = 0;

void* Packet::operator new(size_t) throw(bad_alloc)
{
for (int p = 0; p < Packet::BUFF_NUM; p++)
{
if (!pool_idx[p])
{
_num++;cout << "[newx] = " << _num << " ";
pool_idx[p] = true;
return pool+p*sizeof(Packet);
}
}
throw bad_alloc();
}

void* Packet::operator new(size_t,Packet* &addr) throw(bad_alloc)
{
for (int p = 0; p < Packet::BUFF_NUM; p++)
{
if (!pool_idx[p])
{
_num++;cout << "[new] = " << _num << " ";
pool_idx[p] = true;
void* pt = pool+p*sizeof(Packet);
memmove(pt,addr,sizeof(Packet));
return pt;
}
}
throw bad_alloc();
}

void Packet::operator delete(void* p) throw()
{
if (p != 0){
_num--;cout << "[del] = " << _num << " ";
pool_idx[((char*)p - pool) / sizeof(Packet)] = false;
}
}


void main()
{
int iNum = 0;
cout << "input num:"; // 0 < num < 75,it's no problem, but num>75....
cin >> iNum;

vector<Packet> v;

for (int i = 0; i<10; i++)
{
v.push_back(Packet());
}

for (int i = 0; i<iNum; i++)
{
v.push_back(Packet());
v.erase(v.begin()); //why delete operator is not called?
}

delete new Packet; //it's ok,delete is called

}
...全文
163 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
helbert 2001-08-31
  • 打赏
  • 举报
回复
holyfire说的对,你应该将该delete函数放在类申明的外面。不要是成员函数
hp1200 2001-07-29
  • 打赏
  • 举报
回复
up
hp1200 2001-07-29
  • 打赏
  • 举报
回复
up
tangtao 2001-04-23
  • 打赏
  • 举报
回复
谢谢myan

最开始,我并没有重载operator new(size_t,Packet* &addr),而是上面一个,但是编译器报未找到一个匹配的,于是我就根据它的出错信息照猫画虎做了一个,呵呵!!
刚才跟踪了一下stl源代码,确实在删除的时候只调用析构函数!
真是该打,忘了Allocator这个默认的东西了,看来该从这里入手了,谢谢!!

回去再看看书!!先撤了!
myan 2001-04-23
  • 打赏
  • 举报
回复
tangtao,你可能是无意中触及到了STL中非常深入的问题。我对于这个问题也没有完全
把握,但是可以给你一个参考意见。

首先,你所要做的事情是改变vector<Packet>的内存模式,这个任务标准的做法是自定义
一个PacketAllocator,然后传入vector声明中:
vector<Packet, PacketAllocator> v;
...
显然你的做法是不标准的,出现问题是迟早的事情。比如说
T::operator new(size_t, T*);
这样的定义式,根本不应该出现在实际代码中,因为它只是供STL内部使用。

至于你的问题,原因是很简单的,operator delete只是在回收内存时才被调用,
erase的效果是调用~Packet(),并未主动回收内存,delete当然不会调用。
tangtao 2001-04-23
  • 打赏
  • 举报
回复
呵呵,谢谢关注!

这个问题我觉得确实有点奇怪!
普通的new,delete好像没有问题,但在stl中出问题

如果说vector自己处理内存问题,却为什么只调用new,却不调用delete
看来我得去看看stl原码了!
holyfire 2001-04-23
  • 打赏
  • 举报
回复
呵呵,我没有尝试过,事实好像是这样的。
关注。
tangtao 2001-04-23
  • 打赏
  • 举报
回复
好像我的编译器不允许我声明非void*的delete 运算符
必须是:
void operator delete(void*)

不管是否在class 例外或是友元。
holyfire 2001-04-23
  • 打赏
  • 举报
回复
不要定义在类里面

void operator delete( Packet * );
tangtao 2001-04-23
  • 打赏
  • 举报
回复
holyfire:
我也想这么做,只不过编译器不允许!! :-(
holyfire 2001-04-23
  • 打赏
  • 举报
回复
你重载的是
delete( void * );
而不是
delete( Packet * );

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧