紧急求助, 这样new出来的对象怎么触发其析构函数

wangyaosuper 2009-01-11 05:31:57

class A
{
public:
A(){...}
virtual ~A(){...}
} ;


int main()
{
void *p = malloc(sizeof(A));
A *a = new(p) A();
delete(a); ////这样会coredump,
return 0;
}

请问像这样new出来的对象怎么触发 ~A()的执行, (除了直接调用~A())

紧急,在线等,多谢



...全文
404 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
yshuise 2009-01-12
  • 打赏
  • 举报
回复
飞雪写的代码有错哈。
icesky_ff 2009-01-12
  • 打赏
  • 举报
回复
菜鸟学习 强悍的人物是一个比一个强啊
wangyaosuper 2009-01-12
  • 打赏
  • 举报
回复
而且内存应该也没有释放,后续继续进行操作,乃至free(p)都是正常的。
wangyaosuper 2009-01-12
  • 打赏
  • 举报
回复
可是通过测试,ms是这样,



不重载delete的时候

delete a; 单步跟进去会进入free()函数,如果a是placement-construct的就会coredump在free()里面。



重载了delete之后,

delete a; 的时候只调用了a的析构函数,但是没有进入free()函数,
yutaooo 2009-01-12
  • 打赏
  • 举报
回复

不不!!

delete 包含2部分的操作。

1. 调用对象的析构器。
2. 释放内存。

其中,第2部分,有可能用 free 实现,也有可能用其它方式。

我觉得你又误解了啊 !
wangyaosuper 2009-01-12
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 baihacker 的回复:]
引用 16 楼 wangyaosuper 的回复:
我也测试了一下

placement的情况下

void operator delete(void* t)
{
}


再 delete a;

安全,而且确实会触发a的析构,

飞雪 强悍!!!!

感谢各位大侠!

你malloc的内存呢...借钱不还嗦?
[/Quote]



那当然是要后续free() 的 :)

也就是说这里的delete a; 是不会释放内存的, 只会触发析构, 哈哈, 明白了。



我做的这个咚咚是想实现一个内存池, 因为用g++的malloc有内存碎片影响性能的问题,不适合项目运用的场景

所以需要placement 构造 ,

后来发现placement 构造容易实现, 但是在内存池回收内存块的时候不知道怎么隐式触发对象的析构
(因为对于内存本身,并不知道内存块分配给的对象的类型,所以无法a->A::~A()这样显示地调用),

现在明白了重载delete这个手段, 很受用。

不过还有不理解的地方,为什么重载了delete这个操作后, delete原本的free()功能没有了,但是调用析构函数的功能却保留下来了呢?
zhangyq73 2009-01-12
  • 打赏
  • 举报
回复
new/delete,malloc/free它们操作的是不同的内存区域。
自由存储区:由new/delete分配和释放。对象的生命期可能小于分配的存储空间的生命期。即分配内存不一定要初始化,销毁对象未必要释放空间。
堆区:通过malloc()/free()分配和释放。在某些编译器中,默认的全局的new/delete调用的malloc()/free().在堆中分配的内存不能在自由存储区安全的释放,反之亦然。在堆内存可用在布局new的构造、析够中。
baihacker 2009-01-12
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 yshuise 的回复:]
飞雪写的代码有错哈。
[/Quote]
我只保证在我的测试环境里调用一次.
至于保证内存回收,不关我的事了.
(楼主的"请问像这样new出来的对象怎么触发 ~A()的执行, (除了直接调用~A()) "
这里new本来就只是调用构造函数的方法,而不涉及内存分配
所以应该显示调用析构函数,然后free.
或者利用delete调用析构函数,然后free.
楼主又不让直接用析构,有点故意为难人,所以我第一楼也就故意写了个为难楼主的.
)
楼主题目中也只是问问怎么触发其析构函数.
至于应该怎么做,前面已经有人说明了.
imafish_i 2009-01-11
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 xiaoyisnail 的回复:]
使用placement new间接地调用构造函数初始化对象时,不能用delete操作来销毁由placement new返回的对象的指针,因为placement new并不实际分配内存,仅仅返回一个指向已经分配好空间的指针。此时,为了在销毁对象时,调用对象的析构函数,就应该直接调用对应的析构函数
[/Quote]

支持!
jiahehao 2009-01-11
  • 打赏
  • 举报
回复
mark
xiaoyisnail 2009-01-11
  • 打赏
  • 举报
回复
使用placement new间接地调用构造函数初始化对象时,不能用delete操作来销毁由placement new返回的对象的指针,因为placement new并不实际分配内存,仅仅返回一个指向已经分配好空间的指针。此时,为了在销毁对象时,调用对象的析构函数,就应该直接调用对应的析构函数
waizqfor 2009-01-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 baihacker 的回复:]
C/C++ codea->A::~A();//直接调用好啊
[/Quote]
UP 呵呵
nineforever 2009-01-11
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 wangyaosuper 的回复:]
我也测试了一下

placement的情况下

void operator delete(void* t)
{
}


再 delete a;

安全,而且确实会触发a的析构,

飞雪 强悍!!!!

感谢各位大侠!
[/Quote]

你这样做会导致所以的delete都变成空操作。换言之,如果你程序其它地方使用了普通的new分配空间,那么在你定义了全局“operator delete”以后
int *p=new int;
delete p;
将不会正确释放内存
而你的例子里malloc出来的内存也会泄露
星羽 2009-01-11
  • 打赏
  • 举报
回复
既然用placement new 那就显示调用析构
nineforever 2009-01-11
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 FoxOnWeb 的回复:]
1, 显示调用析构函数最好

2, 重载placement delete与重载placement new 成对用
[/Quote]

C++里没有“placement delete”的概念
FoxOnWeb 2009-01-11
  • 打赏
  • 举报
回复
1, 显示调用析构函数最好

2, 重载placement delete与重载placement new 成对用
baihacker 2009-01-11
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 wangyaosuper 的回复:]
我也测试了一下

placement的情况下

void operator delete(void* t)
{
}


再 delete a;

安全,而且确实会触发a的析构,

飞雪 强悍!!!!

感谢各位大侠!
[/Quote]
你malloc的内存呢...借钱不还嗦?
wangyaosuper 2009-01-11
  • 打赏
  • 举报
回复
我也测试了一下

placement的情况下

void operator delete(void* t)
{
}


再 delete a;

安全,而且确实会触发a的析构,

飞雪 强悍!!!!

感谢各位大侠!



baihacker 2009-01-11
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 wangyaosuper 的回复:]
还有如果加了
void operator delete(void* t)
{
}

再 delete a; 会调用到a的析构函数吗?
[/Quote]
gcc下测试,调用过一次.
yutaooo 2009-01-11
  • 打赏
  • 举报
回复

2 楼已经说的很清楚了呀。显示调用析构函数呀。
加载更多回复(13)

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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