你在线程函数中执行了delete pCalc;
第1个执行到这里的线程把结构给释放了,其它线程得到的数据无法预料。

解决方案 »

  1.   

    delete pCalc;

    delete this;
    到底想干什么
      

  2.   

    1,3楼,他那两delete都没问题得,而且是属于比较正确得处理方法
      

  3.   

    你创建了多个线程。其中有一个线程delete pCalc。该对象已被释放了。
      

  4.   

    看清楚了,人家delete前已经把所有感兴趣的东西保存好了,后来再也没用那个结构,这样的代码没见过,怀疑你以前都没正确传过结构给线程。上面是比较好的做法之一
      

  5.   

    书上面也是这样说的,删除this是因为我用CreateEx()这个方法创建窗口,书上面面说退出程序的时候要把this给释放掉
    我就郁闷我用变量接收结构里面的地址,值都是垃圾的???
    是不是应为我用了.net 2008 的原因,
    我用VC++6.0在试试
      

  6.   

    LS可能没注意到,LZ是用一个循环创建多个线程,把new出来的同一个指针传给了每一个线程,在每个线程中都会delete一次,其它就多不说了。
      

  7.   

    问题不是delete this,而是delete pCalc。
      

  8.   


    #include <AfxWin.h>
    #include "resource.h"
    #include "ThreadTest.h"
    #define IDC_EDIT_MAX 100
    #define IDC_EDIT_MIN 101
    #define IDC_EDIT_TN  102
    #define IDC_EDIT_PO  103
    #define IDC_BUTTON_CACL 104
    #define IDC_LIST_MESSAGE 105
    #define WM_USER_THREAD WM_USER + 0x01typedef struct tagCALCINFO {
    HWND hWnd;
    int nMax;
    int nMin;
    int nThreadNumber;
    CCriticalSection* pCs;
    }CALCINFO;CMyApp myApp;BOOL CMyApp::InitInstance()
    {
    // TODO: 在此添加专用代码和/或调用基类
    m_pMainWnd = new CMainWindow;
    m_pMainWnd->ShowWindow(m_nCmdShow);
    m_pMainWnd->UpdateWindow();
    return TRUE;
    }CMainWindow::CMainWindow()
    {
    CString strWndClass = AfxRegisterWndClass(
    0,
    myApp.LoadStandardCursor(IDC_ARROW),
    (HBRUSH)(COLOR_3DFACE + 1),
    myApp.LoadStandardIcon(IDI_INFORMATION)
    );
    CreateEx(0, strWndClass,_T("ThreadTest"),WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU,
    CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,NULL);
    CRect rect(0,0,800,600);
    CalcWindowRect(&rect); SetWindowPos(NULL,1000, 400, 300, 420,SWP_NOZORDER|SWP_NOMOVE|SWP_NOREDRAW);
    // Create(NULL,_T("ThreadTest"),WS_OVERLAPPEDWINDOW,CRect(500,200,800,600));
    }BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)
    ON_WM_CREATE()
    ON_BN_CLICKED(IDC_BUTTON_CACL, OnButtonCacl)
    END_MESSAGE_MAP()int CMainWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
    return -1; // TODO:  在此添加您专用的创建代码 if (!m_wndStatic1.Create(_T("累加开始于:"),WS_VISIBLE|WS_CHILD|WS_EX_LEFT|WS_BORDER,
    CRect(3,3,70,23),this,IDC_STATIC))
    return -1;

    if (!m_wndEditMin.Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|WS_BORDER,
    CRect(3,26,203,49),this,IDC_EDIT_MIN))
    return -1;
    m_wndEditMin.SetWindowText(_T("0")); if (!m_wndStatic2.Create(_T("累加结束于:"),WS_VISIBLE|WS_CHILD|WS_EX_LEFT|WS_BORDER,
    CRect(3,52,70,72),this,IDC_STATIC))
    return -1; if (!m_wndEditMax.Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|WS_BORDER,
    CRect(3,75,203,98),this,IDC_EDIT_MAX))
    return -1;
    m_wndEditMax.SetWindowText(_T("10000")); if (!m_wndStatic3.Create(_T("使用线程数量:"),WS_VISIBLE|WS_CHILD|WS_EX_LEFT|WS_BORDER,
    CRect(3,101,70,121),this,IDC_STATIC))
    return -1; if(!m_wndEditTN.Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|WS_BORDER,
    CRect(3,124,103,147),this,IDC_EDIT_TN))
    return -1;
    m_wndEditTN.SetWindowText(_T("2")); if(!m_wndButtonCacl.Create(_T("开始计算"),WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON|BS_VCENTER|BS_CENTER,
    CRect(106,124,206,147),this,IDC_BUTTON_CACL))
    return -1; if(!m_wndStatic5.Create(_T("累加结果:"),WS_VISIBLE|WS_CHILD|WS_EX_LEFT|WS_BORDER,
    CRect(3,150,80,173),this,IDC_STATIC))
    return -1; if(!m_wndEditPO.Create(WS_CHILD|WS_VISIBLE|ES_AUTOHSCROLL|WS_BORDER,
    CRect(3,176,203,199),this,IDC_EDIT_PO))
    return -1; return 0;
    }void CMainWindow::OnButtonCacl()
    {
    m_wndEditPO.SetWindowText(_T("0"));

    m_wndEditMax.GetWindowText(strMax);
    m_wndEditMin.GetWindowText(strMin);
    m_wndEditTN.GetWindowText(strThreadNumber);

    int nMax, nMin, nThreadNumber;
    nMax = _ttoi(strMax);
    nMin = _ttoi(strMin);
    nThreadNumber = _ttoi(strThreadNumber); m_wndButtonCacl.EnableWindow(FALSE);
    for(int i=1; i<=nThreadNumber; i++)
    {
    CALCINFO* calcinfo = new CALCINFO;
    calcinfo->hWnd = m_hWnd;
    calcinfo->nMax = nMax;
    calcinfo->nMin = nMin;
    calcinfo->nThreadNumber = nThreadNumber;
    calcinfo->pCs = &m_cs;
    AfxBeginThread(ThreadFunc, calcinfo);
    }
    }UINT ThreadFunc(LPVOID pPrama)
    {
    CALCINFO* pCalc = (CALCINFO*)pPrama;
    int nMax = pCalc->nMax;
    int nMin = pCalc->nMin;
    int nThreadNumber = pCalc->nThreadNumber;
    HWND hWnd = pCalc->hWnd;
    CCriticalSection* pCs = pCalc->pCs;
    delete pCalc;
    long nStep = (nMax - nMin + 1) / nThreadNumber;
    long beginValue = nMin + nStep * (nThreadNumber -1);
    long endValue = beginValue + nStep;
    long result = 0;
    for (long i=beginValue; i<endValue; i++)
    {
    result += i;
    }
    pCs->Lock();
    long sum = 0;
    sum += result;
    ::PostMessage(hWnd, WM_USER_THREAD, (WPARAM)sum, 0);
    pCs->Unlock();
    return 0;
    }LRESULT CMainWindow::OnThreadFinished(WPARAM wParam, LPARAM lParam)
    {
    int nResult = (int)wParam;
    CString strResult;
    strResult.Format("%d",nResult);
    m_wndEditPO.SetWindowText(strResult);
    m_wndButtonCacl.EnableWindow(TRUE);
    return 0;
    }void CMainWindow::PostNcDestroy()
    {
    // TODO: 在此添加专用代码和/或调用基类 delete this;
    }
      

  9.   

    确实,楼主应该每个线程new一个,而不是在循环外new一个然后给每个线程都同一个指针
      

  10.   

    建议你先这样看一下,在nMax = _ttoi(strMax);和int nMax = pCalc->nMax;之后都加入如下代码:
    CString message;
    message.Format("%d", nMax);
    AfxMessageBox(message);
    只用一个线程试一下,看两次输出的结果是否相同。
      

  11.   

    两边都相等,但是我后面的nResult的值等于0
      

  12.   

    你这个又没有共享数据,要lock干吗?至于返回值不对,在Postmessage前加个断点,跟踪一下吧
      

  13.   

    共享谁了?sum不是你线程内部定义得么?
      

  14.   

    nResult的值与Max、Min和nThreadNumber的值有关,测试的时候Max给大一些就不是0了,例如:Max=100, min=1, nThreadNumber=3这样试试。
    另外你那个sum根本没意义。
      

  15.   

    如果你想统计所有线程之中得和,sum就不能这么定义,可以考虑定义成那个窗口得一个成员对象,然后在消息处理函数中求和,这样就簿需要锁了
      

  16.   

    + hWnd 0x00130830 {unused=2228285 } HWND__ *
    我把SUM定义为全局变量了,而且用了一个进程锁呀
    pCs->Lock();
    sum += result;
    ::PostMessage(hWnd, WM_USER_THREAD, (WPARAM)sum, 0);
    pCs->Unlock();
      

  17.   

    try the following:step 1:
    Add the follwing data members in CMainWindow.hh
    private: 
    int m_nMax;
    int m_nMin;
    int m_nThreadNumber;public:
    int getMax(){return m_nMax;}
    int getMin(){return m_nMin;}
    int getThreadNumber(return m_nThreadNumber;}step 2:
    void CMainWindow::OnButtonCacl()
    {
        m_wndEditPO.SetWindowText(_T("0"));    
            
        m_wndEditMax.GetWindowText(strMax);
        m_wndEditMin.GetWindowText(strMin);
        m_wndEditTN.GetWindowText(strThreadNumber);
        
        m_nMax = _ttoi(strMax);
        m_nMin = _ttoi(strMin);
        m_nThreadNumber = _ttoi(strThreadNumber);    m_wndButtonCacl.EnableWindow(FALSE);
        
        for(int i=1; i<=nThreadNumber; i++)
        {
            AfxBeginThread(ThreadFunc, this);
        }
    }step 3:
    UINT ThreadFunc(LPVOID pPrama)
    {
        CMainWindow* pData = (CMainWindow*)pPrama;
        int nMax = pData->getMax();
        .
        .
        .
        ::SendMessage(pData->m_hWnd, WM_USER_THREAD, (WPARAM)sum, 0);
        return 0x0;
    }
      

  18.   

    多个线程都在delete pCalc;但是只在他们的父线程中new;