读书人

有关问题找到可不知道有关问题出现的

发布时间: 2012-08-24 10:00:20 作者: rapoo

问题找到,可不知道问题出现的原因,求分析
情况:
在一个DLL中,有窗口类TfmQuotTG,窗口类TQuotDModule(无关的就不列举了)
窗口类TfmQuotTG中成员:

Private:
ZQInfo tmpZQ;

自定义了一个消息:MESSAGE_HANDLER(WM_USER_INFORM_TIMEROPEN, TMessage, OpenTimer)
消息处理函数:

MESSAGE void __fastcall TfmQuotTG::OpenTimer(TMessage & Message)
{
memset(&tmpZQ, 0, sizeof(ZQInfo));
memcpy(&tmpZQ, (ZQInfo *)Message.WParam,sizeof(ZQInfo));
Timer1->Enabled = true;
}

void __fastcall TfmQuotTG::Timer1Timer(TObject *Sender)
{
Memo1->Lines->Add(this->Name);
Memo1->Lines->Add(tmpZQ.m_strzqdm);
}

窗口类TQuotDModule中成员
Private:
ZQInfo m_stZqinfo;

void __fastcall TQuotDModule::InformHqTimerOpen(HWND hwnd)
{
ZQInfo *ZQINFO;
ZQINFO = new ZQInfo();
memcpy(ZQINFO, &m_stZqinfo, sizeof(ZQInfo));
SendMessage(hwnd, WM_USER_INFORM_TIMEROPEN, (WPARAM)ZQINFO, 1);
delete ZQINFO ;//这行代码注销和不注销出现两种情况
}

现在程序执行流程:

1.实例化类TfmQuotTG的a1, 实例化类TQuotDModule对象B

2.给B中的m_stZqinfo赋值

3.调用B->InformHqTimerOpen(a1)给对象a1发送消息,

4.a1接受到消息后处理消息

//通过memo中内容看显示情况

情况1.如果我注销掉 delete ZQINFO 这行代码,memo显示内容如下:
this->name tmpZQ.m_strzqdm
fmQuot 000001
fmQuot 000001
... ...
内容正常显示

情况2,如果我不注销掉 delete ZQINFO 这行代码,memo显示内容如下
this->name tmpZQ,m_stzqdm
fmQuot
fmQuot
....
tmpZQ结构体的值变为空了,

问题分析:
1.用SendMessage(hwnd, WM_USER_INFORM_TIMEROPEN, (WPARAM)ZQINFO, 1),将ZQINFO值传到窗口a1;
2.a1接收到消息后,就将ZQINFO的值memcpy拷贝到a1的私有成员变量tmpZQ中,
3.等a1处理完消息,sendmessage返回后,再delete ZQINFO

为什么delete ZQINFO 后会影响到a1中的tmpZQ值呢, 我已经在处理消息的时候将消息中的值memcpy拷贝
到tmpZQ中了啊
搞不懂啊,求指点啊



[解决办法]
需要看ZQInfo 的完整定义。

因为你用的是 memcpy 进行浅复制,如果 ZQInfo 有指针成员或有 String 这类使用类似于智能指针的成员,是会产生这种情况的。
例:
ZQInfo
{
String v ;
};
ZQInfo a ,b;
a.v = "test";
memcpy(&b,&a,sizeof(ZQInfo ));//这就是不安全的了。

应该使用对象赋值语义: b = a ; //这样就没有该问题.

读书人网 >C++ Builder

热点推荐