内存清理问题 [英] Memory Cleanup problem

查看:54
本文介绍了内存清理问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从Java迁移到C ++,我仍然对内存的某些方面感到困惑

清理操作。


例如,让's'说我有一个类MovingObject,它维护一个指向另一个类MovementAlgorithm的指针。


MovingObject有一个方法

SetMovementAlgorithm(MovementAlgorithm) * movementAlgorithm)


如果此方法的主体读取

{

this-> movementAlgorithm = movementAlgorithm;

}


这是每次设置一个新的MovementAlgorithm时的内存泄漏(其他比第一次更多的b $ b)?因为先前的移动算法是不是被b
删除了?


处理这个问题的正确方法是什么?


如果我将方法的主体更改为如下所示:


if(this-> movementAlgorithm!= NULL){

删除此 - > movementAlgorithm;

}

this-> movementAlgorithm = movementAlgorithm;


程序崩溃。 MovingObject的所有构造函数

将指针变量初始化为NULL或通过新的

运算符。谁能解释一下呢?

Moving to C++ from Java, I''m still confused by some aspects of memory
cleanup operations.

For example, let''s say I have a class MovingObject which maintains a
pointer to another class MovementAlgorithm.

MovingObject has a method
SetMovementAlgorithm(MovementAlgorithm* movementAlgorithm)

if the body of this method reads
{
this->movementAlgorithm = movementAlgorithm;
}

is this a memory leak every time a new MovementAlgorithm is set (other
than the first time)? Because the previous movement algorithm isn''t
deleted?

What is the correct way to handle this problem?

If I change the body of the method to read as follows :

if (this->movementAlgorithm != NULL) {
delete this->movementAlgorithm;
}
this->movementAlgorithm = movementAlgorithm;

I get program crash. All of the constructors for MovingObject
initialize the pointer variable either to NULL or through the new
operator. Can anyone explain this?

推荐答案

2004年7月31日星期六18:58:25 +0100,Jonathan Ames< am ** @ reb。有机>写道:
On Sat, 31 Jul 2004 18:58:25 +0100, Jonathan Ames <am**@reb.org> wrote:
从Java迁移到C ++,我仍然对内存清理操作的某些方面感到困惑。

例如,让我说我有一个类MovingObject,它维护一个指向另一个类MovementAlgorithm的指针。

MovingObject有一个方法
SetMovementAlgorithm(MovementAlgorithm * movementAlgorithm)
{
this-> movementAlgorithm = movementAlgorithm;
}
这是每次新的MovementAlgorithm时内存泄漏设置(其他比第一次)?因为以前的移动算法没有被删除?


这里没有内存泄漏,因为这里没有分配内存,

它是你使用* SetMovementAlgorithm导致内存的方式

泄漏。


我认为你正在使用它这样的东西


MovingObject x;

x.SetMovementAlgorithm(new MovementAlgorithm); // 1

....

x.SetMovementAlgorithm(new MovementAlgorithm); // 2


这里有一个内存泄漏,因为指向步骤1中分配的

对象的唯一指针已在步骤2被覆盖,并且所以

对象永远不会被删除。


但在这个类似的代码中没有内存泄漏


MovingObject x;

MovementAlgorithm y1;

x.SetMovementAlgorithm(& y1);

....

MovementAlgorithm y2;

x.SetMovementAlgorithm(& y2);

处理这个问题的正确方法是什么?


取决于。

如果我将方法的主体更改为如下所示:

if(this-> movementAlgorithm!= NULL){
删除this-> movementAlgorithm;
}
this-> movementAlgorithm = movementAlgorithm;

我的程序崩溃了。 MovingObject的所有构造函数都将指针变量初始化为NULL或通过新的
运算符。任何人都可以解释这个吗?
Moving to C++ from Java, I''m still confused by some aspects of memory
cleanup operations.

For example, let''s say I have a class MovingObject which maintains a
pointer to another class MovementAlgorithm.

MovingObject has a method
SetMovementAlgorithm(MovementAlgorithm* movementAlgorithm)

if the body of this method reads
{
this->movementAlgorithm = movementAlgorithm;
}

is this a memory leak every time a new MovementAlgorithm is set (other
than the first time)? Because the previous movement algorithm isn''t
deleted?
There is no memory leak here because there is no memory allocated here,
it''s the way that you *use* SetMovementAlgorithm that causes the memory
leak.

I think you are using it something like this

MovingObject x;
x.SetMovementAlgorithm(new MovementAlgorithm); // 1
....
x.SetMovementAlgorithm(new MovementAlgorithm); // 2

Here there is a memory leak, because the only pointer pointing to the
object allocated at step 1 has been overwritten at step 2, and so that
object can never be deleted.

But in this similar code there is no memory leak

MovingObject x;
MovementAlgorithm y1;
x.SetMovementAlgorithm(&y1);
....
MovementAlgorithm y2;
x.SetMovementAlgorithm(&y2);

What is the correct way to handle this problem?

It depends.
If I change the body of the method to read as follows :

if (this->movementAlgorithm != NULL) {
delete this->movementAlgorithm;
}
this->movementAlgorithm = movementAlgorithm;

I get program crash. All of the constructors for MovingObject
initialize the pointer variable either to NULL or through the new
operator. Can anyone explain this?




没有看到更多的代码。我想崩溃最可能的原因是你要删除相同的内存两次因为你没有为
定义一个合适的复制构造函数或类的赋值运算符

MovingObject。复制MovingObject对象时,您正在复制

movementAlgorithm数据成员,因此最终会删除两次相同的内存

。但这只是一个猜测。


所有这些问题的解决方案是使用指针以较少骑士的方式。我不知道你要实现什么,但这里有一些建议。


1)你真的需要使用指针?你能否定义

这样的MovingObject


class MovingObject

{

...

MovementAlgorithm movementAlgorithm;

};


2)如果你确实需要指针,那么请阅读三个规则 ''。当你在一个类中包含一个指针时,你几乎总是需要定义

适当的复制构造函数和该类的赋值运算符。我怀疑你不是那样做的,虽然我不知道,因为你没有发布代码。


3)一旦你开始使用new分配对象,那么你必须考虑

关于释放指针的责任。换句话说,谁是
拥有指针。你已经描述了你的MovingObject类的方式,所以

听起来好像MovementAlgorithm对象是在

MovingObject类之外分配的,但是MovingObject对象取得了
调用SetMovementAlgorithm时的
指针。你是否高兴和清楚

那个?


4)了解智能指针,它可以解决
$ b中的许多问题$ b自动正确释放已分配的对象。例如,有一个

查看来自boost
http://www.boost.org/libs/smart_ptr/smart_ptr.htm 。它可能正好是你需要的价格。


如果这一切都没有帮助,那么发布Movingbject的定义和

MovementAlgorithm,我会再看看。


john



Not without seeing more code. I guess the most likely reason for the crash
is that you are deleteing the same memory twice because you have not
defined a suitable copy constructor or assignment operator for the class
MovingObject. When a MovingObject object is copied you are copying the
movementAlgorithm data member and hence end up deleting the same memory
twice. But that is only a guess.

The solution to all these problems is to use pointer in a less cavalier
fashion. I don''t know exactly what you are tring to achieve but here are
some suggestions.

1) To you really need to use pointers at all? Could you not define
MovingObject like this

class MovingObject
{
...
MovementAlgorithm movementAlgorithm;
};

2) If you really do need pointers then read up on the ''rule of three''. as
soon as you include a pointer in a class you almost always need to define
proper copy constructors and assignment operators for that class. I
suspect that you are not doing that, although I don''t know because you
didn''t post the code.

3) As soon as you start allocating objects using new, then you must think
about whose responsiblity it is to free that pointer. In other words who
owns the pointer. The way you have described your MovingObject class so
far it sounds as if the MovementAlgorithm object is allocated outside the
MovingObject class but a MovingObject object takes ownership of the
pointer when SetMovementAlgorithm is called. Are you happy and clear about
that?

4) Learn about smart pointers, which take care of many of the problems in
correctly freeing allocated objects automatically. For instance have a
look at the shared_ptr class available from boost
http://www.boost.org/libs/smart_ptr/smart_ptr.htm. It could be exactly
what you need.

If all this doesn''t help then post the definitions for Movingbject and
MovementAlgorithm and I''ll take another look.

john


" Jonathan Ames" <上午** @ reb.org>写道...
"Jonathan Ames" <am**@reb.org> wrote...
从Java迁移到C ++,我仍然对内存清理操作的某些方面感到困惑。

例如,让''我说我有一个类MovingObject,它维护一个指向另一个类MovementAlgorithm的指针。

MovingObject有一个方法
SetMovementAlgorithm(MovementAlgorithm * movementAlgorithm)

如果这个方法的主体读取了
{
this-> movementAlgorithm = movementAlgorithm;
}
这是每次设置一个新的MovementAlgorithm时内存泄漏(其他比第一次?)?因为以前的移动算法没有被删除?


可能。也就是说,如果''运动算法''实际上被_ / $
分配了某人使用''new''。一个''MovingObject''显然拥有

指针的所有权(并负责从那里释放内存)

所以如果你只是复制值,那么价值通常会丢失。

处理这个问题的正确方法是什么?


取决于具体情况。

如果我改变方法的主体如下:

if(this- > movementAlgorithm!= NULL){
删除this-> movementAlgorithm;


此处不需要''if''。 ''删除NULL''什么都不做。

}
this-> movementAlgorithm = movementAlgorithm;

我让程序崩溃了。


更有可能是因为''运动算法''

指向的内存当你试图删除它时,并没有使用' 'new''。

MovingObject的所有构造函数都将指针变量初始化为NULL或通过新的
运算符。任何人都可以解释这个吗?
Moving to C++ from Java, I''m still confused by some aspects of memory
cleanup operations.

For example, let''s say I have a class MovingObject which maintains a
pointer to another class MovementAlgorithm.

MovingObject has a method
SetMovementAlgorithm(MovementAlgorithm* movementAlgorithm)

if the body of this method reads
{
this->movementAlgorithm = movementAlgorithm;
}

is this a memory leak every time a new MovementAlgorithm is set (other
than the first time)? Because the previous movement algorithm isn''t
deleted?
Probably. That is, if ''movementAlgorithm'' in fact _was_ allocated by
somebody using ''new''. A ''MovingObject'' apparently takes ownership of
the pointer (and is responsible for releasing the memory from there on)
so if you simply copy the value, the previous value is usually lost.

What is the correct way to handle this problem?
Depends on the situation.

If I change the body of the method to read as follows :

if (this->movementAlgorithm != NULL) {
delete this->movementAlgorithm;
There is no need for the ''if'' here. ''delete NULL'' does nothing.
}
this->movementAlgorithm = movementAlgorithm;

I get program crash.
It is more likely because the memory to which the ''movementAlgorithm''
points when you try to delete it, wasn''t allocated using ''new''.
All of the constructors for MovingObject
initialize the pointer variable either to NULL or through the new
operator. Can anyone explain this?




我猜可以。如果所有这些都实际上是使用''new''分配的,

则问题可能是多次删除同一个对象。

当然,它'和任何其他人一样,没有看到完整的代码就好了。


C ++指针很棘手。动态分配对象的指针

甚至更棘手。他们需要很多关注。这就是为什么它通常建议初学者不要使用它们。


Victor



I could guess. If all of them were in fact allocated using ''new'',
then the problem can be in deleting the same object more than once.
Of course, it''s just as good a guess as anybody else''s who hasn''t
seen the complete code.

C++ pointers are tricky. Pointers to dynamically allocated object
are even trickier. They require a lot of attention. That''s why it
is often recommended that beginners don''t use them.

Victor

2004年7月31日下午7:58,Jonathan Ames写道:
On 7/31/2004 7:58 PM, Jonathan Ames wrote:
如果此方法的主体读取了
{
this-> movementAlgorithm = movementAlgorithm ;
}

这是每次设置一个新的MovementAlgorithm时的内存泄漏(其他比第一次)?因为以前的移动算法没有被删除?


如果第一个MovementAlgorithm对象是在程序中某处的

堆上动态创建的,则必须放在某处删除

对它采取行动,因为会发生泄密。


因此,可能的解决方案之一是检查MovingObject的本地成员是否是

(指向MovementAlgorithm的指针) )

是否为空:


{

//破坏现有的算法。对象

if(this-> movementAlgorithm!= NULL)

删除this-> movementAlgorithm;


//分配新的

this-> movementAlgorithm = movementAlgorithm;

}


但是你必须跟踪movementAlgorithm成员NULL''ity ,
我的意思是你必须在MovingObject构造函数

或初始化列表中为它指定NULL,如果你不指定新的算法。但你有
,即名为DetachAlgoFromMovingObject()的方法;清除

它你必须再次分配NULL所以当你分配新的算法。

再次对象时,MovingObject假设的NULL'nity将

是真的,所以不会执行算法破坏。


我不知道你的所有代码但我认为声明

this-> myPointer是Java习惯;-)

如果你没有任何指针强制转换(基础或派生类)

和动态(虚拟) )多态性我认为

你可以简单地用这种方式编写代码:


{

//破坏现有的算法。对象

if(movementAlgorithm!= NULL)

删除this-> movementAlgorithm;


//分配新的

movementAlgorithm = movementAlgorithm;

}


处理此问题的正确方法是什么?


以上只是我的想法,但我不保证这是

最正确的方式。

如果我将方法的主体更改为如下所示:

if(this-> movementAlgorithm!= NULL){
删除this-> movementAlgorithm;
}
this-> movementAlgorithm = movementAlgorithm;


呵呵呵呵!

我刚看到它;-))在我写完我的想法之后,所以

我离开了它并且在小组上发帖但是很有趣。

在我写答案之前我没有读完你的帖子;-)

我得到程序崩溃。 MovingObject的所有构造函数都将指针变量初始化为NULL或通过新的
运算符。任何人都可以解释一下这个吗?
if the body of this method reads
{
this->movementAlgorithm = movementAlgorithm;
}

is this a memory leak every time a new MovementAlgorithm is set (other
than the first time)? Because the previous movement algorithm isn''t
deleted?
If the first MovementAlgorithm object was created dynamicaly on the
heap somewhere in your program, you have to place somewhere delete
action on it, because leaks will occur.

So, one of the possible solution would be to check if
the local member of MovingObject (pointer to MovementAlgorithm)
is null or not:

{
// Destroy existing algo. object
if (this->movementAlgorithm != NULL)
delete this->movementAlgorithm;

// Assign new one
this->movementAlgorithm = movementAlgorithm;
}

But you have to track movementAlgorithm member NULL''ity,
I mean you have to assign NULL to it in MovingObject constructor
or initialization list and if you don''t assign new algo. but you have
i.e. method called DetachAlgoFromMovingObject(); which clears
it you have to again assign NULL so when you assign new algo.
to the object again, NULL''ity of MovingObject assumption will
be true, so no destruction of algorithm will be performed.

I don''t know your all code but I think that the statement
this->myPointer is on oe Java habit ;-)
If you don''t have any pointer casts (to base or derived class)
and dynamic (virtual) polymorphism I think
that you can simply write the code above this way:

{
// Destroy existing algo. object
if (movementAlgorithm != NULL)
delete this->movementAlgorithm;

// Assign new one
movementAlgorithm = movementAlgorithm;
}

What is the correct way to handle this problem?
The above is only my idea, but I don''t guarantee it is the
most correct way.
If I change the body of the method to read as follows :

if (this->movementAlgorithm != NULL) {
delete this->movementAlgorithm;
}
this->movementAlgorithm = movementAlgorithm;
Hehehehe !
I''ve just seen it ;-)) after I wrote my idea, so
I leave it and post on group but it''s funny.
I didn''t read whole your post before I write my answer ;-)
I get program crash. All of the constructors for MovingObject
initialize the pointer variable either to NULL or through the new
operator. Can anyone explain this?




你必须自己为指针指定NULL。

知道指针的默认构造函数

为你做这件事。


Greets


-


Mateusz£oskot

mateusz at loskot dot net



You have to assign NULL to pointers by yourself.
There is know default constructor for pointer which would
do it for you.

Greets

--

Mateusz £oskot
mateusz at loskot dot net


这篇关于内存清理问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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