为什么这块会有内存泄漏???

Y_A_N_G 2009-01-02 05:04:43
CMtmsEngine* CMtmsEngine::NewL(MMtmsEngineObserver& aObserver)
{
CMtmsEngine* self = new (ELeave) CMtmsEngine(aObserver);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}

CMtmsEngine::CMtmsEngine(MMtmsEngineObserver& aObserver)
: CActive(0),
iObserver(aObserver),
iIdArray(NULL),
iSmsId(KMsvNullIndexEntryId)
{
m_bReverMsgFlag = EFalse;
iMsvEntry = NULL;
}

void CMtmsEngine::ConstructL()
{
CActiveScheduler::Add(this);
iEntrySelection = new (ELeave) CMsvEntrySelection;
iSession = CMsvSession::OpenAsyncL(*this);
}

void CMtmsEngine::CreateMtmClientL()
{
// Client-side MTM registry.
iClientMtmReg = CClientMtmRegistry::NewL(*iSession);

// Get the SMS Mtm client from the registry
iSmsMtm = static_cast<CSmsClientMtm*>(iClientMtmReg->NewMtmL(KUidMsgTypeSMS));

}

CMtmsEngine::~CMtmsEngine()
{
Cancel();
delete iMsvOper;
delete iEntrySelection;
delete iSmsMtm;
delete iClientMtmReg;
MEMORY_FREE(iMsvEntry );
delete iSession;

if (iIdArray)
{
iIdArray->Reset();
delete iIdArray;
iIdArray = NULL;
}
}

void CMtmsEngine::DoCancel()
{
if (iMsvOper)
{
iMsvOper->Cancel();
delete iMsvOper;
iMsvOper = NULL;
}
}

void CMtmsEngine::RunL()
{
iObserver.HandleMessageSentL(iStatus.Int());


TMsvEntry CMtmsEngine::CreateSMSMessageL(const TDesC& aAddress, const TDesC& aMessage)
{
TMsvEntry indexEntry;
indexEntry.SetInPreparation(ETrue);
indexEntry.iMtm = KUidMsgTypeSMS;
indexEntry.iType = KUidMsvMessageEntry;
indexEntry.iServiceId = iSmsMtm->ServiceId();
indexEntry.iDate.UniversalTime();
iSmsMtm->SwitchCurrentEntryL(KMsvDraftEntryId);
iSmsMtm->Entry().CreateL(indexEntry);
iSmsId = indexEntry.Id();
iSmsMtm->SwitchCurrentEntryL(iSmsId);
CSmsHeader& header = iSmsMtm->SmsHeader();
CSmsSettings* sendOptions = CSmsSettings::NewL();
CleanupStack::PushL(sendOptions);
sendOptions->CopyL(iSmsMtm->ServiceSettings()); // restore existing settings
sendOptions->SetDelivery(ESmsDeliveryImmediately); // set to be delivered immediately
sendOptions->SetCharacterSet(TSmsDataCodingScheme::ESmsAlphabetUCS2) ;
header.SetSmsSettingsL(*sendOptions);
CleanupStack::PopAndDestroy(sendOptions);
CRichText& body = iSmsMtm->Body();
body.Reset();
body.InsertL(0, aMessage);
indexEntry.iDescription.Set(aMessage);
CSuperSMSBookEngine* iBookEngine = CSuperSMSBookEngine::NewL();
TBuf<32> iName;
if (iBookEngine->GetNameByMobile(aAddress, iName))
{
indexEntry.iDetails.Set(iName);
iSmsMtm->AddAddresseeL(aAddress, indexEntry.iDetails);
}
else
{
indexEntry.iDetails.Set(aAddress);
iSmsMtm->AddAddresseeL(aAddress);
}
delete iBookEngine;
iSmsMtm->Entry().ChangeL(indexEntry);
iSmsMtm->SaveMessageL();
return indexEntry;
}
TBool CMtmsEngine::ValidateCreatedSMS()
{
TMsvPartList partsToBeChecked = KMsvMessagePartBody | KMsvMessagePartRecipient |
KMsvMessagePartOriginator | KMsvMessagePartDate;

TMsvPartList failedParts = iSmsMtm->ValidateMessage(partsToBeChecked);

if (failedParts == KMsvMessagePartNone)
{
return ETrue;
}
else
{
return EFalse;
}
}

void CMtmsEngine::SendSMSL()
{
iSmsMtm->SwitchCurrentEntryL(iSmsId);
iSmsMtm->LoadMessageL();
CSmsSettings& serviceSettings = iSmsMtm->ServiceSettings();
const TInt numSCAddresses = serviceSettings.ServiceCenterCount();
if (numSCAddresses > 0)
{
TInt scIndex=0;
scIndex = serviceSettings.DefaultServiceCenter();
if ((scIndex < 0) || (scIndex >= numSCAddresses))
{
scIndex = 0; //???
}
TPtrC serviceCentreNumber =
serviceSettings.GetServiceCenter(scIndex).Address();
iSmsMtm->SmsHeader().SetServiceCenterAddressL(serviceCentreNumber);
}
iSmsMtm->SaveMessageL();
TMsvEntry indexEntry = iSmsMtm->Entry().Entry();
indexEntry.SetInPreparation(EFalse);
indexEntry.SetSendingState(KMsvSendStateWaiting);
iSmsMtm->Entry().ChangeL(indexEntry);
Cancel(); // prepare iMsvOper for use
iEntrySelection->Reset();
iEntrySelection->AppendL(iSmsId);
CMsvEntry* entry = iSession->GetEntryL(KMsvDraftEntryId);//====从这块开始有内存泄漏,就算把entry delete掉也有内存泄漏,到底是哪出错了?
TRAPD(err,entry->CopyL(iSmsMtm->Entry().EntryId(), iSmsMtm->ServiceId(), iStatus));
SetActive();
}

//.h文件=====

#ifndef MTMS_ENGINE
#define MTMS_ENGINE

// INCLUDES
#include <e32base.h> // CBase
#include <msvapi.h> // MMsvSessionObserver
#include <badesca.h> // CDesCArrayFlat

#define MEMORY_FREE(a) if(a){delete a; a=NULL;}

// FORWARD DECLARATIONS
class CClientMtmRegistry;
class CSmsClientMtm;
class MMtmsEngineObserver;

class MMtmsEngineObserver
{
public:
virtual void HandleMessageSentL(TInt aError) = 0;
virtual void MessageReceived(const TDesC& addr, const TDesC& aMobile, const TDesC& msg, const TDesC& adate)=0;
};

class CMtmsEngine : public CActive, public MMsvSessionObserver
{
public:
static CMtmsEngine* NewL(MMtmsEngineObserver& aObserver);
~CMtmsEngine();
public:
void DeleteMessageL(TInt aIndex, TMsvId aFolderId);
void DeleteAllMessage(TMsvId aFolderId);

void SendSMSL();
TMsvEntry CreateSMSMessageL(const TDesC& aAddress, const TDesC& aMessage);
TBool ValidateCreatedSMS();

TTime ParseDateTime(const TDesC& aDateTime);
void ParseDateTime(TTime& time, TDes& aDateTime);
TBool WriteMessageToInbox(CDesCArrayFlat*& aAddr, CDesCArrayFlat*& aMobile,
CDesCArrayFlat*& aMessage,CDesCArrayFlat*& aDateTime);
TBool WriteMessageToOutbox(CDesCArrayFlat*& aAddr, CDesCArrayFlat*& aMobile,
CDesCArrayFlat*& aMessage,CDesCArrayFlat*& aDateTime);
void GetFolderSMSMessageInformation( TMsvId aFolderID,CDesCArrayFlat*& aMobile,
CDesCArrayFlat*& aAddress, CDesCArrayFlat*& aTime,
CDesCArrayFlat*& aMessage);
CMtmsEngine(MMtmsEngineObserver& aObserver);
void ConstructL();
void CreateMtmClientL();

private: // from CActive
virtual void DoCancel();
virtual void RunL();

private: // from MMsvSessionObserver
void HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3);

private:
CSmsClientMtm* iSmsMtm;
MMtmsEngineObserver& iObserver;
CMsvOperation* iMsvOper;
CMsvEntrySelection* iEntrySelection;
CMsvSession* iSession;
CClientMtmRegistry* iClientMtmReg;
RArray<TMsvId>* iIdArray;

// Id of an SMS message
TMsvId iSmsId;
TMsvId iNewMessageId;
CMsvEntry* iMsvEntry;
TBool m_bReverMsgFlag;
};
#endif // MTMS_ENGINE
...全文
219 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
andida168 2010-07-24
  • 打赏
  • 举报
回复
请问你是怎么解决的啊?我按照那样的方法做了后,短信发不出去了!![Quote=引用 11 楼 y_a_n_g 的回复:]
谢谢你, jlxtlinbercsu 问题解决了, 谢谢
[/Quote]
andida168 2010-07-24
  • 打赏
  • 举报
回复
感谢你们,我也遇到这个问题,官方的程序都有错啊!不知道他们怎么测试的
jlxtlinbercsu 2009-01-03
  • 打赏
  • 举报
回复
客气了,一起学习一下而已。
Y_A_N_G 2009-01-03
  • 打赏
  • 举报
回复
谢谢你, jlxtlinbercsu 问题解决了, 谢谢
beyondma 2009-01-03
  • 打赏
  • 举报
回复
iSession像是他的问题,他释放了吗?
jlxtlinbercsu 2009-01-03
  • 打赏
  • 举报
回复
TRAPD(err,iOper = entry->CopyL(iSmsMtm->Entry().EntryId(), iSmsMtm->ServiceId(), iStatus));应该可以用的。
Y_A_N_G 2009-01-03
  • 打赏
  • 举报
回复
那TRAPD是不是就用不上了??
jlxtlinbercsu 2009-01-03
  • 打赏
  • 举报
回复
在类里面定义一个CMsvOperation型的成员指针就可以了吧。
Y_A_N_G 2009-01-03
  • 打赏
  • 举报
回复
请问一下 jlxtlinbercsu ,后面这个指针怎么释放? 就是CopyL函数返回的指针, 我没用指针接收呀,不好意思,我刚入门不久。
jlxtlinbercsu 2009-01-03
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jlxtlinbercsu 的回复:]
2.TRAPD(err,entry->CopyL(iSmsMtm->Entry().EntryId(), iSmsMtm->ServiceId(), iStatus));楼主用的这个CopyL返回值不是整型的
[/Quote]
刚刚这里说错了。注意这个返回的CMsvOperation型指针,我猜应该是要delete.
jlxtlinbercsu 2009-01-03
  • 打赏
  • 举报
回复
1.CMsvEntry* entry = iSession->GetEntryL(KMsvDraftEntryId); 这个entry用完之后要delete掉。SDK上有说明的:
IMPORT_C CMsvEntry *GetEntryL(TMsvId aEntId);
Description
Accesses the entry with the specified ID.

If a client is unaware of the entries that exist, it can set aId to KMsvRootIndexEntryId to obtain the root entry, from where all other entries can be obtained.

The CMsvEntry object must be deleted by the client when it is no longer required.


2.TRAPD(err,entry->CopyL(iSmsMtm->Entry().EntryId(), iSmsMtm->ServiceId(), iStatus));楼主用的这个CopyL返回值不是整型的,参考:
IMPORT_C CMsvOperation* CopyL(TMsvId aMsvId, TMsvId aTargetId, TRequestStatus& aStatus);
返回的CMsvOperation类型指针应该也是要删除的,SDK上好像没说,楼主试试吧。
qingtiancao 2009-01-03
  • 打赏
  • 举报
回复
首先:你要确定是不是内存泄漏!

其次:要明白能引起内存泄露的原因有很多,比如:delete了一个不属于自己的指针,new了却没有delete,多次delete同一块内存等,都会引起内从泄漏,如果真正是内存泄露引起的,最简单,也是最笨的方法:采用回溯法,全部注释掉已确定的可能引起内存泄露的代码,然后一点一点的将代码放出来,直到找到问题为止

最后:分析到底是此异常代码引起的内存泄露,找到原因并解决


像楼主这样将整片代码贴出来,即使有人仔细看了也不一定能找到异常的原因(很可能错误代码不再此段代码内)

自己的代码只有自己最明白,要找出错误不是很难

楼主加油吧!

Y_A_N_G 2009-01-02
  • 打赏
  • 举报
回复
我用return ; 当我把return 放在 “CMsvEntry* entry = iSession->GetEntryL(KMsvDraftEntryId); 前面时没有内存泄漏, 而放在它后面时就是内存泄漏,就算加了delete , 还是内存泄漏
lius1984 2009-01-02
  • 打赏
  • 举报
回复
内存泄漏你咋查出来的? 用HookLogger? 报什么错,kern exec -3?
避免内存泄漏主要检查1)堆内存new了有没有及时delete。 2)多用栈内存传递参数而不是堆内存
MMP里把epocheapsize和epocstacksize适当设大一些试试
在C++语言中,如果需要动态分配一块内存,程序员需要负责这块内存的整个生命周期。从申请分配、到使用、再到最后的释放。这样的过程非常灵活,但是却十分繁琐,程序员很容易由于疏忽而忘记释放内存,从而导致内存的泄露。Java语言对内存管理做了自己的优化,这就是垃圾回收机制。Java的几乎所有内存对象都是在堆内存上分配(基本数据类型除外),然后由GC(garbage collection)负责自动回收不再使用的内存。     上面是Java内存管理机制的基本情况。但是如果仅仅理解到这里,我们在实际的项目开发中仍然遇到内存泄漏的问题。也许有人表示怀疑,既然Java的垃圾回收机制能够自动的回收内存,怎么还出现内存泄漏的情况呢?这个问题,我们需要知道GC在什么时候回收内存对象,什么样的内存对象被GC认为是“不再使用”的。     Java中对内存对象的访问,使用的是引用的方式。在Java代码中我们维护一个内存对象的引用变量,通过这个引用变量的值,我们可以访问到对应的内存地址中的内存对象空间。在Java程序中,这个引用变量本身既可以存放堆内存中,又可以放在代码栈的内存中(与基本数据类型相同)。GC线程从代码栈中的引用变量开始跟踪,从而判定哪些内存是正在使用的。如果GC线程通过这种方式,无法跟踪到某一块堆内存,那么GC就认为这块内存将不再使用了(因为代码中已经无法访问这块内存了)。

3,120

社区成员

发帖
与我相关
我的任务
社区描述
塞班系统(Symbian系统)是塞班公司为手机而设计的操作系统,它的前身是英国宝意昂公司的 EP ( Electronic Piece of cheese)操作系统。
社区管理员
  • Symbian社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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