急问:MFC框架下使用ACE库产生的内存泄露问题。

llm06 2010-08-30 02:03:57
我在mfc框架下面使用了ACE库的一些功能:线程,ace_singleton等等,现在碰到一个问题,在程序退出时会产生大量的内存泄露,
我在initinstance里面已经增加了ace::init,在exitinstance时调用了ace::fini,
我程序中定义了一些线程继承自ace_task,然后把线程类作为ace_singleton模版的类。
后发现ace_singleton模版中的线程指针并没有被释放,这和各种文档中的解释不符合,这是什么原因呢?
该如何解决,请指点,谢谢!
...全文
175 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
llm06 2010-08-30
  • 打赏
  • 举报
回复
走题了,这里不是讨论析构函数的问题.
不知道是我没说清楚还是您理解有问题,我没说程序要调用析构函数,当指针被delete的时候,析购函数是会被调用的。

我想要知道的是,为什么析构函数没有被调用,根据ACE的解释,object manager会清理singleton中的静态对象,但是在mfc框架中却并没有这么做。
qf17331733 2010-08-30
  • 打赏
  • 举报
回复
补充下:析构函数不是用来销毁对象的,只是在对象生存期结束以前给你一个机会释放所占用的资源。本质上析构函数也是一个函数,只要它所属的对象存在,你调用它几次都没问题。但是有时为了能够比较彻底的释放资源,要在析构函数中增加一些delete的语句。一般来说,你手工来调用,并不能保证能正确执行析构函数。析构函数只是做销毁前的动作,销毁动作当然还是由delete(堆对象)或者栈指针的移动(栈对象)来完成。
由编译器完成的销毁动作由于仅仅回收对象直接占用的内存,所以如果对象内还通过指针间接占用了其他内存,或者占用了其他的系统资源(如文件句柄),就需要在对象销毁前通过析构函数来释放。如果类只是个非常简单的类,那么实际上根本不需要显式的析构函数。
最后,从语法上,析构函数也只是个函数而已,仅从语法上考虑的话,我们可以在析构函数中做任何事,当然包括跟对象销毁没有任何关系的事,比如析构函数中仅仅打印一行字符串,其他的什么都不做,这都是可以的。调用多次当然也没任何问题。它只是个函数而已,当然可以调用多次,只要你能保证它里边没有不可以多次调用的语句(比如删除同一块内存)就可以了。析构函数真正不同于一般函数的地方在于:在对象销毁之前,它会被自动调用,而一般函数不会被自动调用。
qf17331733 2010-08-30
  • 打赏
  • 举报
回复
哦~你发一下你的析构函数给我看看吧~
很多时候这些函数社会空值,可以不调用,估计我个人习惯用 delete
另外我刚才也搜了一下,你可以在http://topic.csdn.net/t/20040111/18/2654494.html看下能有对你有帮助的提示不?
llm06 2010-08-30
  • 打赏
  • 举报
回复
析构函数怎么会不被调用呢?

我的意思是,该线程指针未被delete,所以析构函数没有被调用程序就退出了。
qf17331733 2010-08-30
  • 打赏
  • 举报
回复
~CStoreThread()不用调用~有这句话就说明了在class CStoreThread{}里的函数是析构函数~
不过有些地方需要用到delect~
llm06 2010-08-30
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qf17331733 的回复:]
资料不足,大脑无法运行~
在你这些程序中,只有virtual ~CStoreThread();会通过重载释放~
应该还有大量的公共函数没有通过delete释放。
[/Quote]

问题在于,~CStoreThread()析构函数并没有被调用。
qf17331733 2010-08-30
  • 打赏
  • 举报
回复
给你一段参考代码:
#include "Client.h"

using namespace ACE_Client;

int main(int argc, char *argv[])
{
Client client("localhost"); //服务器的IP地址或者服务器名称

for(int i = 0; i < 5; i++)
{
char *task1 = "Is it a good day?"; //第1个task的数据
size_t task1_len = 18; //第1个task的数据长度
char *task1_t; //无需修改
ACE_NEW_RETURN(task1_t, char[task1_len + 4], -1); //无需修改
client.put_task(task1_t, task1, task1_len); //无需修改

char *task2 = "Yeah, it really is."; //第2个task的数据
size_t task2_len = 20; //第2个task的数据长度
char *task2_t; //无需修改
ACE_NEW_RETURN(task2_t, char[task2_len + 4], -1); //无需修改
client.put_task(task2_t, task2, task2_len); //无需修改

client.send_tasks(); //将上面的task全部发到服务器

delete [] task1_t; //释放task1的内存
delete [] task2_t; //释放task2的内存
}
return 0;
}
qf17331733 2010-08-30
  • 打赏
  • 举报
回复
资料不足,大脑无法运行~
在你这些程序中,只有virtual ~CStoreThread();会通过重载释放~
应该还有大量的公共函数没有通过delete释放。
llm06 2010-08-30
  • 打赏
  • 举报
回复
把一部分贴上来:
class CStoreThread : public ACE_Task<ACE_MT_SYNCH>
{
friend class ACE_Singleton<CStoreThread, ACE_Thread_Mutex>;

public:

CStoreThread();
virtual ~CStoreThread();

int Start();

int Stop();

private:

/// Service of thread. Implementation of class ACE_Task
virtual int svc();


};

typedef ACE_Singleton<CStoreThread, ACE_Thread_Mutex> CStoreThreadSingleton;
#define STORE_THREAD CStoreThreadSingleton::instance()

在initinstance,
BOOL CVTrackManagerApp::InitInstance()
{
int nRet = ACE::init();

在exitinstance
int CVTrackManagerApp::ExitInstance()
{
// TODO: Add your specialized code here and/or call the base class
int nRet = ACE::fini();
return CWinApp::ExitInstance();
}


qf17331733 2010-08-30
  • 打赏
  • 举报
回复
看一下你设的公共函数~如果有代码发出来看看那更好~

24,854

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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