在debug窗口里出现这个打印信息:ASSERT_VALID fails with illegal vtable pointer.
First-chance exception in MONCALL.exe (KERNEL32.DLL): 0xC0000005: Access Violation.
First-chance exception in MONCALL.exe (MFC42D.DLL): 0xC0000005: Access Violation.有时候不会有异常,正常退出。但也会打印:
ASSERT_VALID fails with illegal vtable pointer.
First-chance exception in MONCALL.exe (KERNEL32.DLL): 0xC0000005: Access Violation.请大虾指教,是什么问题?

解决方案 »

  1.   

    整个程序是很长的。不过关于多线程的部分并不多:在主窗口类中定义了一个CDbWriter子线程类成员,程序一启动就创建子线程。 但是子线程一开始不做什么事。直接关闭程序就有时会出现异常。这个程序有两个子线程,我把其中一个关掉了(程序启动时不创建)。然后现在又不怎么出现异常了。debug窗口中也不常有异常信息。通常是我在我修改了程序后,第一次编译执行后会有异常信息打印,然后再运行几次,都是正常的。
    class CDlg : public CDialog
    {
    // Construction
    public:
    CDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data
    //{{AFX_DATA(CDlg)
    enum { IDD = IDD_MONCALL_DIALOG };
    // NOTE: the ClassWizard will add data members here
    //}}AFX_DATA // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
    //}}AFX_VIRTUAL CDbWriter *m_pdbMonWriter;

    ..............
    }int CDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) 
    {
       ................
    m_pdbMonWriter  = new CDbWriter(DBODBC_DSN_MON);
    VERIFY(m_pdbMonWriter);
        if (!m_pdbMonWriter->CreateThread(CREATE_SUSPENDED))
    {
    delete m_pdbMonWriter;
    }
        else
            m_pdbMonWriter->ResumeThread();}void CDlg::OnDestroy() 
    {
    CDialog::OnDestroy();

    // TODO: Add your message handler code here
    //释放对象
        ..........
        if ( m_pdbMonWriter != NULL )
    delete m_pdbMonWriter;
        ...........}//子线程类
    class CDbWriter : public CWinThread
    {
        DECLARE_DYNCREATE(CDbWriter)
    protected:
        CDbWriter();      // protected constructor used by dynamic creationpublic:
        CDbWriter(char *pDsnName);      // protected constructor used by dynamic creation// Attributes
    public:
        CCriticalSection DataCritical;      C2Database   * m_pdb ;
        C2Recordset  * m_prs ;
        
        queue<CString> m_queueSqlStr;private:
        CEvent m_RcvMsgEvent; 
        HANDLE m_hEventKill;// Operations
    public:
    void MsgArrive(void);
        BOOL SqlExec(CString szQuery );// Overrides
    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CDbWriter)
    public:
    virtual BOOL InitInstance();
    virtual int ExitInstance();
    //}}AFX_VIRTUAL// Implementation
    public:
    virtual ~CDbWriter(); // Generated message map functions
    //{{AFX_MSG(CDbWriter)
    // NOTE - the ClassWizard will add and remove member functions here.
    //}}AFX_MSG DECLARE_MESSAGE_MAP()
    };// CDbWriterIMPLEMENT_DYNCREATE(CDbWriter, CWinThread)CDbWriter::CDbWriter()
    {
    }CDbWriter::CDbWriter(char *pDsnName)
    {
    //kill event starts out in the signaled state
    m_hEventKill = CreateEvent(NULL, TRUE, FALSE, NULL);

    //这里面有一些打开数据库的过程,}CDbWriter::~CDbWriter()
    {}BOOL CDbWriter::InitInstance()
    {
    // TODO:  perform and per-thread initialization here
    while (WaitForSingleObject(m_hEventKill, 0) == WAIT_TIMEOUT)
        {
    if(WaitForSingleObject(m_RcvMsgEvent, RECVCALLINTERT) == WAIT_OBJECT_0)
            {        }
        } return TRUE;
    }int CDbWriter::ExitInstance()
    {
    // TODO:  perform any per-thread cleanup here
    return CWinThread::ExitInstance();
    }
    BEGIN_MESSAGE_MAP(CDbWriter, CWinThread)
    //{{AFX_MSG_MAP(CDbWriter)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()BOOL CDbWriter::SqlExec(CString szQuery)
    {
    //    SqlExec(szQuery, m_pdb, m_prs);
         return TRUE;

    }/////////////////////////////////////////////////////////////////////////////
    // CDbWriter message handlers
    void CDbWriter::MsgArrive()
    {
        m_RcvMsgEvent.SetEvent();
    }
      

  2.   

    ASSERT_VALID fails with illegal vtable pointer.???
      

  3.   

    我只看到你创建线程,暂停线程,没有看到你有关闭线程啊?
    你退出前把线程关闭掉看看?
    TerminateThread
    CloseHandle
      

  4.   

    to  DentistryDoctor:
      就是这个:ASSERT_VALID fails with illegal vtable pointer. 是什么意思呢to毒药:
      我是模拟以前别人的程序写的。那个程序没有执行TerminateThread和closehandle.to ydfivy:
      如何才叫让线程自己返回呢
      

  5.   

    很奇怪,似乎是因为程序一开始连接了数据库的原因我在App里连接了数据库。如果去掉那段代码,那么就没有问题(我重复启动退出多次都没有问题)另外有个问题,如果不连接数据库,那么退出时,程序打印的信息中,只有两个线程:
    The thread 0x8D4 has exited with code 0 (0x0).
    The thread 0x844 has exited with code 0 (0x0).如果连接了数据库,那么会打印4个线程出来:
    The thread 0xBB8 has exited with code 0 (0x0).
    The thread 0x948 has exited with code 0 (0x0).
    The thread 0xA34 has exited with code 0 (0x0).
    The thread 0x9BC has exited with code 0 (0x0).我明明只有主线程和另外一个创建的子线程,为什么会多出两个出来呢