新建/删除与声明/垃圾收集 [英] New/delete vs. declare/garbage-collect

查看:51
本文介绍了新建/删除与声明/垃圾收集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到如果我给MY_STRUCT一个简单的c''tor和d'tor,比如说,


MY_STRUCT :: MY_STRUCT()

{

hEvent = CreateEvent(...);

}

MY_STRUCT :: ~MY_STRUCT

{

CloseHandle(hEvent);

}


然后通过简单的声明使用本地实例,


INT my_function()

{

MY_STRUCT foo;

// blah

返回0;

}


将近6KB(大部分在.text段中)添加到我的目标DLL中,与

相比,通过它新/删除。有人可以解释为什么会这样吗?上面的例子

只是略微简化了一下。实际的struct有一个HANDLE成员,一个
BOOL和一个OVERLAPPED但仍然是我想要的唯一初始化是

HANDLE。谢谢!

-

- Vince

I noticed that if I give MY_STRUCT a simple c''tor and d''tor, say,

MY_STRUCT::MY_STRUCT()
{
hEvent = CreateEvent(...);
}
MY_STRUCT::~MY_STRUCT
{
CloseHandle(hEvent);
}

then using a local instance via simple declaration,

INT my_function()
{
MY_STRUCT foo;
// blah
return 0;
}

adds nearly 6KB (most in the .text segment) to my target DLL when compared to
using it via new/delete. Can someone explain why that happens? The example
above is just a little simplified. The actual struct has as members a HANDLE, a
BOOL, and an OVERLAPPED but still the only initialization I want is for the
HANDLE. Thanks!
--
- Vince

推荐答案

让我问同样的问题另一个方式(我希望更多)。我使用这样的

ENUM_INFO(如下所述)结构:


INT函数()

{

ENUM_INFO EnumInfo;

// blah

EnumWindows(...,& EnumInfo);

// blah

返回0;

}


结构及其c''tor和d'tor看起来像这样:


struct ENUM_INFO

{

HANDLE hPipe;

BOOL bGlobal;

OVERLAPPED重叠;

ENUM_INFO();

~ENUM_INFO();

};

ENUM_INFO :: ENUM_INFO( )

{

Overlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

Overlapped.Offset = Overlapped.OffsetHigh = 0 ;

};

ENUM_INFO :: ~ENUM_INFO()

{

//CloseHandle(Overlapped.hEvent );

};


很简单,当我取消注释CloseHandle()调用(没有其他更改

)我的目标DLL的大小增加了6KB(mos在

..text段)。 CloseHandle()没有什么特别之处;使用任何WIN32 API函数(例如,Beep()或Sleep())都会观察到相同的情况。

发生了什么?


如果我使用new / delete实例化ENUM_INFO,我看不到尺寸的增加。


谢谢。

-

- Vince
Let me ask the same question another way (more to the point I hope). I use an
ENUM_INFO (described below) struct like this:

INT function()
{
ENUM_INFO EnumInfo;
//blah
EnumWindows(..., &EnumInfo);
// blah
return 0;
}

The struct and its c''tor and d''tor look like this:

struct ENUM_INFO
{
HANDLE hPipe;
BOOL bGlobal;
OVERLAPPED Overlapped;
ENUM_INFO();
~ENUM_INFO();
};
ENUM_INFO::ENUM_INFO()
{
Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
Overlapped.Offset = Overlapped.OffsetHigh = 0;
};
ENUM_INFO::~ENUM_INFO()
{
//CloseHandle(Overlapped.hEvent);
};

Quite simply, when I uncomment the CloseHandle() call (no other changes
anywhere) in the d''tor, my target DLL increases in size by 6KB (most in the
..text segment). There''s nothing special about CloseHandle(); the same will be
observed with any WIN32 API function in its place(e.g., Beep() or Sleep()).
What''s going on?

If I instantiate an ENUM_INFO using new/delete, I don''t see the size increase.

Thanks.
--
- Vince


Vincent Fatica写道:
Vincent Fatica wrote:

Let我用另一种方式问同样的问题(我希望更多的话)。

我使用这样的ENUM_INFO(如下所述)结构:


INT函数()

{

ENUM_INFO EnumInfo;

// blah

EnumWindows(...,& EnumInfo );

// blah

返回0;

}


结构及其c 'tor and d'tor看起来像这样:


struct ENUM_INFO

{

HANDLE hPipe;

BOOL bGlobal;

OVERLAPPED Overlapped;

ENUM_INFO();

~ENUM_INFO();

} ;

ENUM_INFO :: ENUM_INFO()

{

Overlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

Overlapped.Offset = Overlapped.OffsetHigh = 0;

};

ENUM_INFO :: ~ENUM_INFO()

{

//CloseHandle(Overlapped.hEvent);

};


很简单,当我取消注释CloseHandle()调用时(没有其他的

在任何地方发生变化),我的目标DLL的大小增加了

6KB(大多数在.text段)。

CloseHandle();没什么特别的。任何WIN32 API函数

代替它(例如,Beep()或Sleep())。发生了什么?


如果我使用new / delete实例化一个ENUM_INFO,我看不到尺寸增加了b

Let me ask the same question another way (more to the point I hope).
I use an ENUM_INFO (described below) struct like this:

INT function()
{
ENUM_INFO EnumInfo;
//blah
EnumWindows(..., &EnumInfo);
// blah
return 0;
}

The struct and its c''tor and d''tor look like this:

struct ENUM_INFO
{
HANDLE hPipe;
BOOL bGlobal;
OVERLAPPED Overlapped;
ENUM_INFO();
~ENUM_INFO();
};
ENUM_INFO::ENUM_INFO()
{
Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
Overlapped.Offset = Overlapped.OffsetHigh = 0;
};
ENUM_INFO::~ENUM_INFO()
{
//CloseHandle(Overlapped.hEvent);
};

Quite simply, when I uncomment the CloseHandle() call (no other
changes anywhere) in the d''tor, my target DLL increases in size by
6KB (most in the .text segment). There''s nothing special about
CloseHandle(); the same will be observed with any WIN32 API function
in its place(e.g., Beep() or Sleep()). What''s going on?

If I instantiate an ENUM_INFO using new/delete, I don''t see the size
increase.



你的代码中有多少个地方在创建这种类型的局部变量?

每一个地方都需要添加代码到函数epilog

销毁不会出现的对象,除非你明确删除它。

可能更重要的是,有一个析构函数会导致任何函数

包含具有异常帧和异常处理代码的对象
如果你用-GX,-EHa或-EHs编译
(换句话说,

如果您打开了异常处理 - 它默认情况下在2005年开启)。在

交换额外代码大小时,代码代码将在

异常情况下正常运行。


-cd

How many places in your code are you creating local variables of this type?
Every single one of them will entail adding code to the function epilog to
destroy the object that won''t be there unless you explicitly delete it.
Probably more importantly, having a destructor will cause any function
containing the object to have an exception frame and exception handling code
generated for it if you''re compiling with -GX, -EHa or -EHs (in other words,
if you have exception handling turned on - it''s on by default in 2005). In
exchange for that extra code size you code code will behave correctly in the
face of exceptions.

-cd


2006年12月14日星期四21:12:40 -0800,Carl Daniel [VC ++ MVP]

< cp * ****************************@mvps.org.nospamwr ote:
On Thu, 14 Dec 2006 21:12:40 -0800, "Carl Daniel [VC++ MVP]"
<cp*****************************@mvps.org.nospamwr ote:

> Vincent Fatica写道:
>Vincent Fatica wrote:

>让我以另一种方式提出同样的问题(我希望更多)。
我使用的是ENUM_INFO(如下所述)结构如下:

INT函数()
{
ENUM_INFO EnumInfo;
// blah
EnumWindows(..., & EnumInfo);
// blah
返回0;
}

结构及其c''tor和d'tor看起来像这样:

struct ENUM_INFO
{
HANDLE hPipe;
BOOL bGlobal;
覆盖重叠;
ENUM_INFO();
~ENUM_INFO( );
};
ENUM_INFO :: ENUM_INFO()
{
Overlapped.hEvent = C reateEvent(NULL,TRUE,FALSE,NULL);
Overlapped.Offset = Overlapped.OffsetHigh = 0;
};
ENUM_INFO :: ~ENUM_INFO()
{
// CloseHandle(Overlapped.hEvent);
};

很简单,当我取消注释d'中的CloseHandle()调用(没有其他任何地方的变化) tor,我的目标DLL的大小增加了6KB(大多数在.text段中)。
CloseHandle()没有什么特别之处;任何WIN32 API函数(例如,Beep()或Sleep())都会观察到相同的情况。发生了什么?

如果我使用new / delete实例化ENUM_INFO,我看不到尺寸增加。
>Let me ask the same question another way (more to the point I hope).
I use an ENUM_INFO (described below) struct like this:

INT function()
{
ENUM_INFO EnumInfo;
//blah
EnumWindows(..., &EnumInfo);
// blah
return 0;
}

The struct and its c''tor and d''tor look like this:

struct ENUM_INFO
{
HANDLE hPipe;
BOOL bGlobal;
OVERLAPPED Overlapped;
ENUM_INFO();
~ENUM_INFO();
};
ENUM_INFO::ENUM_INFO()
{
Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
Overlapped.Offset = Overlapped.OffsetHigh = 0;
};
ENUM_INFO::~ENUM_INFO()
{
//CloseHandle(Overlapped.hEvent);
};

Quite simply, when I uncomment the CloseHandle() call (no other
changes anywhere) in the d''tor, my target DLL increases in size by
6KB (most in the .text segment). There''s nothing special about
CloseHandle(); the same will be observed with any WIN32 API function
in its place(e.g., Beep() or Sleep()). What''s going on?

If I instantiate an ENUM_INFO using new/delete, I don''t see the size
increase.


你的代码中有多少个地方在创建这种类型的局部变量?


How many places in your code are you creating local variables of this type?



只有一个地方。

Only one place.


>每一个都需要在函数中添加代码epilog来破坏那些不会在那里的对象,除非你明确删除它。
可能更重要的是,拥有一个析构函数会导致包含该对象的任何函数都有一个异常框架和如果您正在使用-GX,-EHa或-EHs进行编译,则为其生成异常处理代码(换句话说,如果您启用了异常处理,则为
- 默认情况下它处于打开状态2005)。在交换额外的代码大小时,代码代码将在异常面前正确运行。
>Every single one of them will entail adding code to the function epilog to
destroy the object that won''t be there unless you explicitly delete it.
Probably more importantly, having a destructor will cause any function
containing the object to have an exception frame and exception handling code
generated for it if you''re compiling with -GX, -EHa or -EHs (in other words,
if you have exception handling turned on - it''s on by default in 2005). In
exchange for that extra code size you code code will behave correctly in the
face of exceptions.



好​​吧,看起来编译器疯狂了。如果我让事情变得更复杂

这样复杂:


ENUM_INFO :: ENUM_INFO(BOOL boo,HANDLE hoo)

{

bGlobal = boo;

hPipe = hoo;

Overlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

Overlapped.Offset = Overlapped.OffsetHigh = 0;

};


ENUM_INFO :: ~ENUM_INFO()

{

CloseHandle(Overlapped.hEvent);

CloseHandle(hPipe);

};


并将它用作这样的局部变量:


ENUM_INFO EnumInfo(stristr(psz,L" / G")?TRUE:FALSE,

CreateNamedPipe(szPipeName,PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,

PIPE_WAIT,1,0,sizeof(EVENT),2000,NULL));


我的DLL从上面提到的设置中减去6KB。

-

- Vince

Well, it looks like compiler madness to me. If I make things a bit more
complicated, like this:

ENUM_INFO::ENUM_INFO(BOOL boo, HANDLE hoo)
{
bGlobal = boo;
hPipe = hoo;
Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
Overlapped.Offset = Overlapped.OffsetHigh = 0;
};

ENUM_INFO::~ENUM_INFO()
{
CloseHandle(Overlapped.hEvent);
CloseHandle(hPipe);
};

And use it as a local variable like this:

ENUM_INFO EnumInfo(stristr(psz, L"/G") ? TRUE : FALSE,
CreateNamedPipe(szPipeName, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED,
PIPE_WAIT, 1, 0, sizeof(EVENT), 2000, NULL));

My DLL drops the 6KB it gained from the set-up mentioned above.
--
- Vince


这篇关于新建/删除与声明/垃圾收集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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