在MainFrame 中声明数组:
public:
CTemp Tmp[8];在函数中调用下面操作的时候会偶尔出现非法写操作(50%的概率)
Tmp[i].IOState= 1;
Tmp[i].funcState = 4;改为如下没有事了
if(this)
{
    Tmp[i].IOState= 1;
    Tmp[i].funcState = 4;
}
为什么?

解决方案 »

  1.   

    恐怕你的函数有在对象初始化之前就被调用的可能。
    所以加上那个判断就会避免函数在this指针为空(就是对象没有初始化之前)访问成员。
      

  2.   

    楼上的解释应该不对。调用myclass类对象myclassobj的成员函数opt1(...),会被编译器解释为myclass(&myclassobj,...),为了区分一个类的不同对象,所以,如下的调用myclassobj.opt1(...)其实是myclass::opt1(&myclassobj,...).第一个参数(&myclassobj)就是this指针。如果this无效,你有怎么找到函数体呢,这不可能。
    楼主的问题,没见过。
      

  3.   

    这个不应该啊
    我把调用顺序写一下吧
    在OnCreate中调用初始化程序
    {
       InitMyData()
       在InitMyData中对Tmp[i].IOState已经进行过数据付值操作
       在InitMyData最后建立线程
       AfxBeginThread(MyThread,GetSafeHwnd(),THREAD_PRIORITY_NORMAL);
    }
    在MyThread执行过程中
    对Tmp[i].IOState进行重新付值的时候出错
    说不能写,如果在此处用
    CMainFrame* pMF=(CMainFrame*)AfxGetApp()->m_pMainWnd;
    pMF->Tmp[i].IOState = 1;
    解决,可以,没错了,但是下面又报告数据不能读出
    if(Tmp[i].IOState == 1)       //出错
    实在令人很奇怪?
      

  4.   

    是否多线程数据共享问题,EnterCriticalSection
      

  5.   

    你那个i是不是越界了? 它只能取0到7的值。
    用之前加个ASSERT检查一下。
      

  6.   

    仅仅创建了一个线程啊,而且这个数据是MyThread线程把发生的事件参数传递给CMainFrame::MyMainProcess(int evt_d,int evt_type)解决
    在MyMainProcess中继续调用CMainFrame中的各个函数处理不同情况。
    出错的是MyMainProcess调用其中一个函数的时候错了。在前几天,出过错,后发现只要窗体藏起来就出错,今天呢,不管窗体在那都出错,迷茫了
    ,这下的好几天研究可是要马上交工了。帮忙啦。
      

  7.   

    i值在很多地方都用到了,没有出界问题。
    如果出界,到这肯定还过不去
    CMainFrame* pMF=(CMainFrame*)AfxGetApp()->m_pMainWnd;
    pMF->Tmp[i].IOState = 1;真的好混蛋的问题
      

  8.   

    把程序发给我,我来看看。[email protected]
      

  9.   

    这个可能会成死问题,我现在只好先用if(this)解决问题,在别的地方见机行事,把漏设的参数补上去  ,靠,真是窝囊,什么问题吗!!!
      

  10.   

    是不是你在其他地方又 定义了Tmp造成引用混乱。
      

  11.   

    这需要专用仪器才能产生事件啊,如果没有事件怎么调试?我怀疑是不是我调用的DLL搞的鬼?我的QQ9062580
    局域网只开了80 和1080 口,没法发邮件。
      

  12.   

    错误在这里 AfxBeginThread(MyThread,GetSafeHwnd(),THREAD_PRIORITY_NORMAL);
    不应传递本窗口的句柄
    OnCreate为完成,本局并可能会有问题
      

  13.   

    public:
    CTemp Tmp[8];
    -------------???CTemp是什么?
    为什么声明为public
    这个习惯不好吧?
      

  14.   

    》如果出界,到这肯定还过不去
    CMainFrame* pMF=(CMainFrame*)AfxGetApp()->m_pMainWnd;
    pMF->Tmp[i].IOState = 1;
    实际上, 若是i出界, 上面的语句绝对可以执行,
    而且不报错。
    只是不知会把什么东西改错了.
      

  15.   

    错误在这里 AfxBeginThread(MyThread,GetSafeHwnd(),THREAD_PRIORITY_NORMAL);
    不应传递本窗口的句柄
    OnCreate为完成,本局并可能会有问题不明白,能结实以下吗?
      

  16.   

    Sorry 我把线程定义成
    UINT MyClass::MyThread(LPVOID pParam)
    改为
    UINT MyThread(LPVOID pParam)
    没事了,谢谢各位捧场
      

  17.   

    不瞒你说我在delphi下也遇到过这样的问题,到现在也没有解决,不过你今天算是提醒了我,
    这也说明了vc相比delphi的一个好处。
    在delphi下,这个问题是很难解决的,
    现在我觉得问题可能出在:
    Tmp[i].IOState= 1;
    Tmp[i].funcState = 4;
    上面的语句访问的内存地址可能是超出了其所在对象的内存地址。导致了不能写的错误。
    解决,可以,没错了,但是下面又报告数据不能读出
    if(Tmp[i].IOState == 1)       //出错
    实在令人很奇怪?
    这里说不能读出我想应该是‘i’在这里是一个不能确定的值吧,一些不成熟的建议仅供参考!!
      

  18.   

    还不行,老毛病 :( 只有在编译->重建全部的时候不出错,如果修改部分代码后用Ctrl + F5编译,就会出错报告的错误是:
    0x004095c9指令引用的内存地址0x000000ee0不能为Write。
      

  19.   

    相关代码如下typedef struct {
    int IOState;     
    int funcState;  
    }CHINFO;class CMainFrame : public CFrameWnd
    {
    protected:
    CHINFO ChInfo[8];
    int InitSys();
    int process(int evt_dev,int evt_type);
    .........
    }int CMainFrame::InitSys()
    {
    .........
    if(bddev) //如果存在设备,则建立线程
    AfxBeginThread(MyThread,NULL);
    return 1;
    }UINT MyThread(LPVOID pParam)
    {
    int evt_dev;
    int evt_type;
    CString TmpStr;
    CMainFrame* pMF=(CMainFrame*)AfxGetApp()->m_pMainWnd;
    while(1)
    {
    if(sr_waitevt(-1) == -1) //事件发生等待

    TmpStr.Format("失败:sr_waitevt():错误码 #%ld.n",ATDV_LASTERR(SRL_DEVICE)); 
    pMF->ShowTxt(TmpStr);
    }
    //取得发生事件的端口和类型
    evt_dev = sr_getevtdev(0);
    evt_type = sr_getevttype(0);
    TmpStr.Format("发生事件为%d",evt_type);
    pMF->ShowTxt(TmpStr);
    pMF->process(evt_dev,evt_type);
    }
    }int CMainFrame::process(int evt_dev, int evt_type)
    {
    switch(evt_type)
    {
    case IDM1A:
    ChInfo[evt_dev].IOState = 1; //出错
    ChInfo[evt_dev].funcState = ST_RINGSRECEIVED;
    break;
     ..........
    }
    return 1;
    }
      

  20.   

    Szhb(隋珠和璧) 说得对!!!
      

  21.   

    我做了个SendMessage把问题解决了,不过为什么会这样呢?
    线程没问题。但这个问题为什么会出现?估计还的研究MFC吧
      

  22.   

    问题原因已经查明
    首先,句柄是什么?是找到一个物件的方式,可以是一个指针(最常见),也可以是一个实体
    比如一个类的对象,操作这个对象的时候,对象的名字就是句柄其实,你的程序也是一个物件,一个实体,所以This指针指的地方就是你程序的鼻子
    当程序还没初始化完成,这时肯定不会存在This指针,只存在内部的已经生成了的对象的指针在我的程序里,在OnCreate处创建线程的时候,This指针并不一定存在,运气好的时候,This指针先于我的程序调用得到,运气不好,我的程序要用数据,但This指针还是0 ,所以出错解决办法就是在线程里加个Sleep(200)就可以了
    谢谢各位捧场