对gcnew和对象的生命周期感到困惑 [英] Confused about gcnew and object lifetime

查看:87
本文介绍了对gcnew和对象的生命周期感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想利用

框架提供的大量功能,所以对于我的最新项目我正在使用带有.NET的托管C ++

V2。我正在以两种不同的方式使用gcnew运算符,而且我对于对象的生命周期以及我是否应该调用delete这两个问题感到困惑。以下是两个例子:


ref class SYMBOL:public IC Comparable

{

public:

//构造函数/析构函数

符号()

{

name = nullptr;

};

~SYMBOL()

{

if(name!= nullptr)

{

删除名称;

}

}


//数据

字符串^名称;

UInt32 relativeAddress;


//方法

虚拟Int32 CompareTo(对象^ obj)

{

MODULE ^ mod = dynamic_cast< MODULE ^>(obj);


返回relative.CompareTo(mod-> relativeAddress);

}

};


在上面的示例中,该类用于创建List

(系统。 SYCES对象的Collections.Generic.List)。对于每个添加

到列表(符号),我做一个SYMBOL对象的gcnew,添加传递给List.Add方法的

gcnew''手柄。我还做了一个String

对象的gcnew,并将gcnew''ed句柄分配给SYMBOL

对象的名称成员。如您所见,我明确地删除了

中的String对象SYMBOL析构函数。这是正确的吗?


另一种情况是:


无效PARSER :: ReadLogFile(无效)

{

FileInfo ^ logFileI = gcnew FileInfo(logFilename);

FileStream ^ logFileS = logFileI-> OpenRead();

logData = gcnew array< Byte>((int)logFileI-> Length);

int bytesRead = logFileS-> Read(logData,0,(int)logFileI-> Length);


删除logFileI;

// TODO:添加一些错误检查,返回0长度

数组的错误机制

}


如你所见,我手动删除了gcnew''ed FileInfo。这是

是否正确?


对不起,如果这是一个基本问题,但我在网上找到的信息

不一致。在一个地方,我发现了一个专家。说'
用gcnew创建的对象永远不应该被删除。但是,那个

对我来说没有意义。我明白,在应用程序退出后,托管堆上的
对象最终将被gc'',但是对于内存管理来说,完全正确的是
,不应该我要删除

我创建的对象?


谢谢,

-Chris

解决方案

我想利用
框架提供的大量功能,所以对于我的最新项目我来说我正在使用带有.NET的托管C ++
v2。我正在以两种不同的方式使用gcnew运算符,而且我对于对象的生命周期以及我是否应该调用delete来感到困惑。这里有两个例子:




是的,


我理解它的方式你必须手动删除对象。 />
C ++ / CLI!= C#


一个月前在这个非常好的讨论中讨论了这个话题。

新闻组(析构函数) :没有被称为gauranteed?):
http://groups.google.nl /group/micros...c2007f860c0a46


它有很多经验丰富的人提供了大量的意见。

这个帖子读得很好如果你想了解更多关于这个话题的话。


-


亲切的问候,

Bruno。
br ********** ************@hotmail.com

仅删除" _nos_pam"


Bruno van Dooren写道:

我想利用大套的由框架提供的功能,所以对于我的最新项目,我正在使用带有.NET的托管C ++
v2。我正在以两种不同的方式使用gcnew运算符,而且我对于对象的生命周期以及我是否应该调用delete来感到困惑。以下是两个例子:

是的,

我理解它的方式你必须手动删除对象。
C ++ / CLI!= C#




C#和C ++ / CLI具有等效的GC AFAIK。 C ++ / CLI GC

的问题与C#(以及Java)的问题完全相同。

一个月前有一个非常热烈的讨论关于在这个非常新闻组中的这个主题(析构函数:不能被称为?):
http://groups.google.nl/group/micros...c2007f860c0a46

很多经验丰富的人都有很多意见。
主题如果你想了解更多关于这个话题的话,请仔细阅读。




我认为你错过了重点(不是我读完整个帖子) - 你做的如果你不关心你的析构函数是否及时(甚至是永久)运行

,那么
就不必调用delete。这适用于Java(我所熟悉的GC熟悉区域),C#和C ++ / CLI。只有当有问题的对象

有一个终结器/析构函数释放非内存资源时,例如

a数据库连接,套接字或文件,你应该手动删除它在

中为了保证及时清理。


基本上,GC擅长在内存不足时回收内存,但它是

显然不知道要最终确定哪些对象以便回收其他资源,例如数据库连接。例如,即使你只有1个/ b $ b可达,你最终也可能会因为可用连接而耗尽
。数据库连接对象,因为GC没有打扰你的b $ b敲定你的旧连接(大概是因为内存不足)。


从本质上讲,GC可以让您从手动内存管理中解脱出来,而不是从手动资源管理中获取。


Tom


< BLOCKQUOTE>>我认为你错过了重点(不是我读完整个帖子) - 你做

如果你不在乎你的析构函数是否运行
及时(甚至永远)。这适用于Java(我熟悉的GC领域),C#和C ++ / CLI。只有当有问题的对象具有释放非内存资源的终结器/析构函数时,例如数据库连接,套接字或文件,您才应该手动删除。它是为了保证及时清理。




嗨汤姆,


我没有错过这一点。在我已经链接到某人的帖子中,

提到了

GC最终(无论何时情绪如何 - 如果有的话 - 如你所说)

执行垃圾收集。

但是,由于很多类涉及物理资源,你必须手动

释放它们如果你想要有一些确定性来防止资源

问题。


因为编程背景中的一切都围绕着一些资源

或其他,

GC无法解决我的任何问题。我关心的资源和关于记忆的资金一样多。


你的评论提醒我,C#也是如此。除了一些测试程序和私人应用程序之外,我只是不使用C#

来支付任何东西

,这就是为什么我没有b $ b没有''想一想。


我同意我应该更具体。

说''你必须手动做如果你想确定它被释放''

会更准确。


-


亲切的问候,

Bruno。
br**********************@hotmail.com

仅删除_nos_pam

I wanted to take advantage of the large set of functionality offered by
the framework, so for my latest project I''m using managed C++ with .NET
v2. I''m using the gcnew operator in two different ways, and I''m
confused about the lifetime of objects and whether or not I should be
calling delete. Here are two examples:

ref class SYMBOL : public IComparable
{
public:
// Constructor / destructor
SYMBOL()
{
name = nullptr;
};
~SYMBOL()
{
if (name != nullptr)
{
delete name;
}
}

//Data
String^ name;
UInt32 relativeAddress;

// Methods
virtual Int32 CompareTo(Object^ obj)
{
MODULE^ mod = dynamic_cast<MODULE^>(obj);

return relative.CompareTo(mod->relativeAddress);
}
};

In the example above, the class is used to create a List
(System.Collections.Generic.List) of SYMBOL objects. For each addition
to the list (symbols), I do a gcnew of a SYMBOL object, add pass the
gcnew''ed handle to the List.Add method. I also do a gcnew of a String
object, and assign the gcnew''ed handle to the name member of the SYMBOL
object. As you can see, I am explicitly deleting the String object in
the SYMBOL destructor. Is this correct?

The other case is this:

void PARSER::ReadLogFile(void)
{
FileInfo^ logFileI = gcnew FileInfo(logFilename);
FileStream^ logFileS = logFileI->OpenRead();
logData = gcnew array<Byte>((int)logFileI->Length);
int bytesRead = logFileS->Read(logData, 0, (int)logFileI->Length);

delete logFileI;
// TODO: Add some error checking, mechanism for returning 0-length
array on error
}

As you can see, I''m manually deleting the gcnew''ed FileInfo. Is this
correct?

Sorry if this is a basic question, but the info I''ve found on the net
is not consistent. In one place I found an "expert" saying that
"objects created with gcnew should never be deleted." However, that
doesn''t make sense to me. I understand that after the app exits,
objects on the managed heap will eventually be gc''ed, but to be
completely right about memory management, shouldn''t I be deleting
objects that I create?

Thanks,
-Chris

解决方案

I wanted to take advantage of the large set of functionality offered by
the framework, so for my latest project I''m using managed C++ with .NET
v2. I''m using the gcnew operator in two different ways, and I''m
confused about the lifetime of objects and whether or not I should be
calling delete. Here are two examples:



Yes,

The way I understood it you have to manually delete the object.
C++/CLI != C#

There was a very lively discussion a month ago about this topic in this very
newsgroup (Destructor: not gauranteed to be called?):
http://groups.google.nl/group/micros...c2007f860c0a46

It had a lot of input from lots of experienced people.
The thread makes a good read if you want to know more about this topic.

--

Kind regards,
Bruno.
br**********************@hotmail.com
Remove only "_nos_pam"


Bruno van Dooren wrote:

I wanted to take advantage of the large set of functionality offered by
the framework, so for my latest project I''m using managed C++ with .NET
v2. I''m using the gcnew operator in two different ways, and I''m
confused about the lifetime of objects and whether or not I should be
calling delete. Here are two examples:

Yes,

The way I understood it you have to manually delete the object.
C++/CLI != C#



C# and C++/CLI have equivalent GC AFAIK. The problems with C++/CLI GC
are the exact same ones as those of C# (and Java for that matter).
There was a very lively discussion a month ago about this topic in this very
newsgroup (Destructor: not gauranteed to be called?):
http://groups.google.nl/group/micros...c2007f860c0a46

It had a lot of input from lots of experienced people.
The thread makes a good read if you want to know more about this topic.



I think you missed the point (not that I read the whole thread) - you do
not have to call delete if you don''t care whether your destructor runs
or not in a timely manner (or even ever). This is true for Java (my area
of GC familiarity), C# and C++/CLI. It is only if the object in question
has a finalizer/destructor that frees up a non-memory resource, such as
a DB connection, socket or file, that you should manually "delete" it in
order to guarantee timely clean up.

Basically, the GC is adept at recycling memory when it gets low, but it
obviously doesn''t know which objects to finalise in order to recycle
other resources, such as db connections. For example, you could end up
running out of available connections even though you only have 1
"reachable" db connection object, since the GC hasn''t bothered to
finalize your old connections (presumably because it isn''t low on memory).

Essentially, GC frees you from manual memory management but not from
manual resource management.

Tom


> I think you missed the point (not that I read the whole thread) - you do

not have to call delete if you don''t care whether your destructor runs
or not in a timely manner (or even ever). This is true for Java (my area
of GC familiarity), C# and C++/CLI. It is only if the object in question
has a finalizer/destructor that frees up a non-memory resource, such as
a DB connection, socket or file, that you should manually "delete" it in
order to guarantee timely clean up.



Hi Tom,

I did not miss that point. In the thread I linked to someone already
mentioned that the
GC will eventually (whenever it is in the mood - if ever - as you say)
perform the garbage collection.
However, since lots of classes involve physical resources you have to manually
release them if you want to have some determinism in it to prevent resource
problems.

Since everything in my programming background revolves around some resources
or other,
The GC cannot solve any of my problems. I care as much about resources as
about memory.

Your remark reminded me that this is also true for C#. I just don''t use C#
for anything
other than some test programs and private applications, which is why I
didn''t think of it.

I agree that I should have been more specific.
Saying ''You have to do it manually If you want to be sure that it is released''
would have been much more precise.

--

Kind regards,
Bruno.
br**********************@hotmail.com
Remove only "_nos_pam"


这篇关于对gcnew和对象的生命周期感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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