从析构函数中删除 [英] Deleting from destructor

查看:97
本文介绍了从析构函数中删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨专家,


这可能很明显,但我找不到任何方式。我们有一个类,它总是使用new分配,例如Foo * foo = new Foo()所以我们

提出了从析构函数释放内存的想法,因为

如下:


Foo :: Foo()

{

//初始化东西

m_This = this; // m_This是void *

}


Foo ::〜Foo()

{

//释放所有资源

//最后是内存

删除m_This;

}


到目前为止它一直工作得很好(Windows和Linux)但是我们想知道

关于它要么做得更糟......任何想法。


谢谢。


问候,


MC

Hi Experts,

This may be obvious but I can''t find anything one way or another. We have
a class which is always allocated using new, e.g. Foo* foo = new Foo() so we
came up with the idea of releasing the memory from the destructor as
follows:

Foo::Foo()
{
// Initialize stuff
m_This = this; // m_This is a "void*"
}

Foo::~Foo()
{
// Release all resources
// and finally the memory
delete m_This;
}

It''s been working fine so far (both Windows and Linux) but we''re wondering
about it being either the worse thing to do..... Any thoughts.

Thank you.

Regards,

MC

推荐答案

mc写道:
mc wrote:

这可能很明显但我找不到任何方法或者另一个。我们有一个类,它总是使用new分配,例如Foo * foo = new Foo()所以我们

提出了从析构函数释放内存的想法,因为

如下:


Foo :: Foo()

{

//初始化东西

m_This = this; // m_This是void *

}


Foo ::〜Foo()

{

//释放所有资源

//最后是内存

删除m_This;

}


到目前为止它一直工作得很好(Windows和Linux)但是我们想知道

关于它要么做得更糟......有什么想法吗。
This may be obvious but I can''t find anything one way or another. We have
a class which is always allocated using new, e.g. Foo* foo = new Foo() so we
came up with the idea of releasing the memory from the destructor as
follows:

Foo::Foo()
{
// Initialize stuff
m_This = this; // m_This is a "void*"
}

Foo::~Foo()
{
// Release all resources
// and finally the memory
delete m_This;
}

It''s been working fine so far (both Windows and Linux) but we''re wondering
about it being either the worse thing to do..... Any thoughts.



这是一个非常糟糕的想法。基本上,调用动态创建的对象的

析构函数的唯一正确方法是使用''delete''

,并将表达式求值为指向该对象的指针宾语。在大多数

的情况下,如果你有
Foo * foo = new Foo();


某处,那么你还有别的地方


删除foo;


这将调用析构函数然后*然后*释放内存。现在,

如果你把指针复制到某个地方(在对象本身,或者在某些地方或其他地方),然后使用''删除''和那个指针,你将

*删除*对象两次。我不确定'删除(无*)ptr''

与''删除ptr'相比有什么(或没有)。因为类型未知,所以很可能无法将析构函数称为
。但它会,而且我肯定它会消耗内存。


所以,如果你确实使用''删除''和'' foo'',你要两次取消分配

内存,这是未定义的行为。如果你不使用''删除

foo'',那么你如何得到析构函数?你明确地称之为

(foo-> ~Foo();)?然后它是相当荒谬的,你应该

而不是使用正常的惯用方式,让系统执行所有必要的清理工作。


V

-

请在通过电子邮件回复时删除资金''A'

我没有回复最热门的回复,请不要问

That is a VERY BAD IDEA. Basically, the only correct way to invoke the
destructor of an object that was created dynamically is to use ''delete''
with the expression evaluating to the pointer to that object. In most
cases if you have

Foo* foo = new Foo();

somewhere, then somewhere else you have

delete foo;

That will invoke the destructor and *then* deallocate the memory. Now,
if you duplicate the pointer somewhere (in the object itself, or in some
other place), and then use ''delete'' with that pointer, you will be
*deleting* the object twice. I am not sure what ''delete (void*)ptr''
does (or does not) compared to ''delete ptr''. Most likely it can''t call
the destructor since the type is unknown. But it will, and I am certain
of it, deallocate the memory.

So, if you do use ''delete'' with your ''foo'', you''re deallocating the
memory twice, which is undefined behaviour. If you don''t use ''delete
foo'', then how do you get the destructor to be called? DO you call it
explicitly (foo->~Foo();)? Then it''s rather nonsensical, you should
instead use the normal idiomatic way and let the system perform all the
necessary clean-up for you.

V
--
Please remove capital ''A''s when replying by e-mail
I do not respond to top-posted replies, please don''t ask


谢谢Victor。我明白你所说和知道的。让我在这里添加更多

上下文,但添加一个更完整的例子:


void SKEL :: bind(const MCU& mcu,...)

{

// const FOO& MCU :: foo()

// {

//返回(* new Foo());

//}

FOO foo = mcu.foo(); //由于返回了const FOO&

,foo变得等于MCU返回的内容:: foo()


//做东西

//当你在这里出现时,FOO的析构函数被调用,内存是

按照之前的帖子发布

}


对象的析构函数只调用一次,没有内存泄漏检测到



MC

" Victor Bazarov" < v。******** @ comAcast.netwrote in message

news:gc ********** @ news.datemas.de ...
Thanks Victor. I understand what you said and knew. Let me put more
context here but adding a more complete example:

void SKEL::bind(const MCU& mcu, ...)
{
// const FOO& MCU::foo()
// {
// return (*new Foo());
// }
FOO foo = mcu.foo(); // Because of the const FOO&
returned, foo becomes equal to what was returned by MCU::foo()

// do stuff
// when exising here, the destructor for FOO is called and the memory is
release as per previous post
}

The destructor for the object is only called once and no memory leaks were
detected.

MC

"Victor Bazarov" <v.********@comAcast.netwrote in message
news:gc**********@news.datemas.de...

mc写道:
mc wrote:

>这可能很明显,但我找不到任何方法或另一个。我们有一个总是使用new分配的类,例如Foo * foo = new
Foo()所以我们提出了从
析构函数中释放内存的想法,如下所示:

Foo :: Foo()
{
//初始化东西
m_This = this; // m_This是一个void *
}

Foo ::〜Foo()
{
//释放所有资源
/ /最后是内存
删除m_This;
}
到目前为止它一直工作得很好(Windows和Linux)但是我们想知道关于它要么是更糟糕的事情.....任何想法。
>This may be obvious but I can''t find anything one way or another. We
have a class which is always allocated using new, e.g. Foo* foo = new
Foo() so we came up with the idea of releasing the memory from the
destructor as follows:

Foo::Foo()
{
// Initialize stuff
m_This = this; // m_This is a "void*"
}

Foo::~Foo()
{
// Release all resources
// and finally the memory
delete m_This;
}

It''s been working fine so far (both Windows and Linux) but we''re
wondering about it being either the worse thing to do..... Any thoughts.



这是一个非常糟糕的想法。基本上,调用动态创建的对象的

析构函数的唯一正确方法是使用''delete''

,并将表达式求值为指向该对象的指针宾语。在大多数

的情况下,如果你有
Foo * foo = new Foo();


某处,那么你还有别的地方


删除foo;


这将调用析构函数然后*然后*释放内存。现在,如果

你在某处复制了指针(在对象本身,或者在某些地方或其他地方),然后使用''删除''和那个指针,你将

*删除*对象两次。我不确定与''删除ptr''相比''删除(无效*)ptr''确实是什么?
(或没有)。因为类型未知,所以很可能无法调用

析构函数。但它会,并且我确定它会释放内存。


所以,如果你确实使用''删除''和'' foo'',你要释放内存

两次,这是未定义的行为。如果你不使用''删除foo'',那么

你如何得到析构函数?你明确地称之为

(foo-> ~Foo();)?然后它是相当荒谬的,你应该使用

正常的惯用方式让系统为你执行所有必要的清理工作




V

-

请在通过电子邮件回复时删除资金''A'

我没有回复最热门的回复,请不要问


That is a VERY BAD IDEA. Basically, the only correct way to invoke the
destructor of an object that was created dynamically is to use ''delete''
with the expression evaluating to the pointer to that object. In most
cases if you have

Foo* foo = new Foo();

somewhere, then somewhere else you have

delete foo;

That will invoke the destructor and *then* deallocate the memory. Now, if
you duplicate the pointer somewhere (in the object itself, or in some
other place), and then use ''delete'' with that pointer, you will be
*deleting* the object twice. I am not sure what ''delete (void*)ptr'' does
(or does not) compared to ''delete ptr''. Most likely it can''t call the
destructor since the type is unknown. But it will, and I am certain of
it, deallocate the memory.

So, if you do use ''delete'' with your ''foo'', you''re deallocating the memory
twice, which is undefined behaviour. If you don''t use ''delete foo'', then
how do you get the destructor to be called? DO you call it explicitly
(foo->~Foo();)? Then it''s rather nonsensical, you should instead use the
normal idiomatic way and let the system perform all the necessary clean-up
for you.

V
--
Please remove capital ''A''s when replying by e-mail
I do not respond to top-posted replies, please don''t ask



mc写道:
mc wrote:

谢谢Victor。我明白你所说和知道的。让我在这里添加更多

上下文,但添加一个更完整的例子:


void SKEL :: bind(const MCU& mcu,...)

{

// const FOO& MCU :: foo()

// {

//返回(* new Foo());

//}

FOO foo = mcu.foo(); //由于返回了const FOO&

,foo变得等于MCU返回的内容:: foo()
Thanks Victor. I understand what you said and knew. Let me put more
context here but adding a more complete example:

void SKEL::bind(const MCU& mcu, ...)
{
// const FOO& MCU::foo()
// {
// return (*new Foo());
// }
FOO foo = mcu.foo(); // Because of the const FOO&
returned, foo becomes equal to what was returned by MCU::foo()



是的。它变成了它的副本。

Yes. It becomes a copy of it.


//做东西

//在这里出现时,调用FOO的析构函数和内存

是按照之前的帖子发布的
// do stuff
// when exising here, the destructor for FOO is called and the memory
is release as per previous post



SKEL :: bind中对象foo的内存是,但还有其他的FOO

动态分配的对象。它仍然在闲逛,而且你已经失去了所有指针,所以你不能解除它。这是一个记忆

泄漏。使用你描述的析构函数,你也碰巧使用了删除带有

a指针指向你没有从new获得的内存,这导致了未定义的

行为。

The memory for the object foo in SKEL::bind is, but there is the other FOO
object that was dynamically allocated. It''s still hanging around, and you
lost all pointers to it, so you can''t ever deallocate it. That''s a memory
leak. With the destructor you described, you also happen to use delete with
a pointer to memory you didn''t get from new, which results in undefined
behavior.


}


对象的析构函数只调用一次,没有内存泄漏检测到

}

The destructor for the object is only called once and no memory leaks were
detected.



听起来你的内存调试器有问题。

Sounds like your memory debugger has a problem.


这篇关于从析构函数中删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆