现在是这样的,我在CProcess类中定义了
typedef struct AccountEncFileList
{
CString arrayUserAccount;
CString arrayUserName;
list<CString> listEncFile;
}ACCOUNT_ENCFILE;
map<CString, ACCOUNT_ENCFILE> m_mapAccountEncFile;
在CProcess.cpp中使用
void CProcess::myProcess()
{
   //初始化保存用户和对应加密文档的列表
   m_mapAccountEncFile.clear();
  for(int iR= 0; iR<4; iR++)
  {
    if ( g_bStopCheckFileType)
    {
     break;
    }
  ....
    pEncrypt.Encrypt(iR, m_ArrayFileName, ArrayEncFile, m_RightInfo, m_dlgProgress, g_bStopCheckFileType);
    int isize = m_mapAccountEncFile.size();
    SortAccountEncFile(userInfo, ArrayEncFile, m_mapAccountEncFile);
  ...
  }
}
Encrypt是自定义的一个加密类中的函数,在Encrypt中
void CEncryptCtrl::Encrypt(int iRow, CStringArray & ArrayFile, CStringArray & ArrayEncFile, CRightInfo pRightInfo, CProgressDlg &dlgProgress, BOOL bStop)
{
   for(int i = 0; i < ArrayFile.GetSize(); i++)
   {
    ...
    pmodEncrypt->DoEncrypt(iRow, strFileName, pRightInfo, strEncFile);
    ArrayEncFile.Add(strEncFile);
    //处理结束
     FinishEncryptMod();
    if (g_bStopCheckFileType)
    {
     return ;
    }
   }
}
其中myProcess是在线程中完成的,g_bStopCheckFileType是全局变量,用于标示当前的操作是否取消。我现在的问题是,当我正常处理文档进行加密并SortAccountEncFile时,isize的值为0,因为m_mapAccountEncFile只是SortAccountEncFile的一个输出参数而已,前面也clear了,但是如果是在程序运行过程中,点击取消,我发现isize就变成了13,但是事实上我在Encrypt中根本没有对m_mapAccountEncFile操作,所以应该是0才对,并且调试时使用m_mapAccountEncFile.clear()就会出现非法访问,请高手指点这是什么原因?

解决方案 »

  1.   

    你是不是对m_mapAccountEncFile使用过[]?如m_mapAccountEncFile[key],这样如果元素key不存在就会在map中安插一个元素(无论你是否进行赋值)。
    另外map不是线程安全的,在m_mapAccountEncFile[key]时会有个堆查找的操作,此时另外一个线程如果有删除操作就会造成访问冲突(常常是因为迭代器失效)。
    =====
    你应该贴跟m_mapAccountEncFile相关的代码,贴那个加密函数完全没有指导意义嘛~
      

  2.   

    跟m_mapAccountEncFile相关的就在这了。不过在 SortAccountEncFile中确实有用过m_mapAccountEncFile[key],不过具体代码要等我上班了才能贴过来,但是在m_mapAccountEncFile[key]之前我有:
    if (g_bStopCheckFileType) 
        { 
         return ; 
        } 那样也会安插一个元素?
    那我要想往map中插入元素,安全的方法是怎么样的呢?
      

  3.   

    安插就map[key] = value  或者map.inset(std::makepair(key,value))都可以,但是使用map[key]之前要判断key是否存在map.find(key) == map.end();否则可能就会安插些无用元素。
    线程安全的话,map的插入、移除操作要手动加锁才行。
      

  4.   

    map进行Clear后,就只有SortAccountEncFile函数对map进行了操作,下面贴出了代码,麻烦看看有没有什么地方不对。
    void CProcess::SortAccountEncFile(USER_INFO & UserInfo, CStringArray &ArrayEncFile, map<CString, ACCOUNT_ENCFILE> & mapAccountEncFile)
    {
    CString strAAccount = "";
    int AccountCount = UserInfo.arrayUserAccount.GetSize();
    int NameCount = UserInfo.arrayUserName.GetSize(); int g = mapAccountEncFile.size();  /////此时g已经变成13了
    if ( g_bStopCheckFileType)
    {
    return ;
    } ACCOUNT_ENCFILE AccountEncFile, newAccountEncFile;

    for(int i = 0; i < AccountCount; i++)
    {
                    strAAccount = UserInfo.arrayUserAccount[i]; map<CString, ACCOUNT_ENCFILE>::iterator it = mapAccountEncFile.begin(); while (it != mapAccountEncFile.end())
    {
    AccountEncFile = (ACCOUNT_ENCFILE)((*it).second); //如果AccountEncFileList列表中存在该用户,则直接将对应的加密后文档加入EncFileList列表
    if(strAAccount == AccountEncFile.arrayUserAccount)
    {
    if(i < NameCount)
    {
    newAccountEncFile.arrayUserName = UserInfo.arrayUserName[i];
    }
    newAccountEncFile = AccountEncFile;
    break;
    } it++;
    }
    //如果AccountEncFileList列表中不存在该用户,则在AccountEncFileList列表尾部增加该用户及对应的EncFileList列表
    if(it == mapAccountEncFile.end())
    {
    newAccountEncFile.arrayUserAccount = strAAccount;
    if(i < NameCount)
    {
    newAccountEncFile.arrayUserName = UserInfo.arrayUserName[i];
    } m_dwAllUserCounts ++;
    } InsertAccountEncFile(newAccountEncFile, ArrayEncFile, mapAccountEncFile);
    }
    }
    void CProcess::InsertAccountEncFile(ACCOUNT_ENCFILE & AccountEncFile, CStringArray & arrayEncFile, map<CString, ACCOUNT_ENCFILE> & mapAccountEncFile)
    {
    AddEncFile(AccountEncFile, arrayEncFile);
    mapAccountEncFile[AccountEncFile.arrayUserAccount] = AccountEncFile;
    }
    设计map的操作都在这里了,是不是我在判断Key是否存在时的方法不对?
      

  5.   

    不好意思,你的帖子沉下去了没看到,结贴才看到。
    你的clear在循环外面的,如果循环第二遍的话,你的map在第一个循环里面可能就已经改变了。typedef struct AccountEncFileList 

    CString arrayUserAccount; 
    CString arrayUserName; 
    list <CString>  listEncFile; 
    }ACCOUNT_ENCFILE; 
    map <CString, ACCOUNT_ENCFILE> m_mapAccountEncFile; 
    void CProcess::myProcess() 

    m_mapAccountEncFile.clear();   //你的清理工作只清理了一次,而下面是4次的循环
    for(int iR= 0; iR <4; iR++) 

    if ( g_bStopCheckFileType) 

    break; 

    .... 
    pEncrypt.Encrypt(iR, m_ArrayFileName, ArrayEncFile, m_RightInfo, m_dlgProgress, g_bStopCheckFileType); 
    int isize = m_mapAccountEncFile.size(); //如果第一个循环改变了容器大小,那么iR>0的时候这里肯定就不是0了,传进去肯定也不是0了。
    SortAccountEncFile(userInfo, ArrayEncFile, m_mapAccountEncFile); 
    ... 

    } void CProcess::SortAccountEncFile(USER_INFO & UserInfo, CStringArray &ArrayEncFile, map <CString, ACCOUNT_ENCFILE>  & mapAccountEncFile) 

    CString strAAccount = ""; 
    int AccountCount = UserInfo.arrayUserAccount.GetSize(); 
    int NameCount = UserInfo.arrayUserName.GetSize();  int g = mapAccountEncFile.size();  /////此时g已经变成13了 ==>应该是到了循环的第二次了
    if ( g_bStopCheckFileType) 

    return ; 
    }  ACCOUNT_ENCFILE AccountEncFile, newAccountEncFile; 
        
        //另外你查找的算法感觉很麻烦,但对你的业务处理不太清楚,
    //map查找可以用map.find(key)查找,返回迭代器,
        //用你比较的字符串做key, 速度也快,也没那么麻烦了
    for(int i = 0; i  < AccountCount; i++) 

    strAAccount = UserInfo.arrayUserAccount[i];  map <CString, ACCOUNT_ENCFILE> ::iterator it = mapAccountEncFile.begin(); 
    //你要保证在循环结束之前没有其他线程对map插入删除,否则可能迭代器失效异常。
    while (it != mapAccountEncFile.end()) 

    AccountEncFile = (ACCOUNT_ENCFILE)((*it).second);  if(strAAccount == AccountEncFile.arrayUserAccount) 

    if(i  < NameCount) 

    newAccountEncFile.arrayUserName = UserInfo.arrayUserName[i]; 

    newAccountEncFile = AccountEncFile; 
    break; 
    }  it++; 


    if(it == mapAccountEncFile.end()) 

    newAccountEncFile.arrayUserAccount = strAAccount; 
    if(i  < NameCount) 

    newAccountEncFile.arrayUserName = UserInfo.arrayUserName[i]; 
    }  m_dwAllUserCounts ++; 
    }  InsertAccountEncFile(newAccountEncFile, ArrayEncFile, mapAccountEncFile); 


    void CProcess::InsertAccountEncFile(ACCOUNT_ENCFILE & AccountEncFile, CStringArray & arrayEncFile, map <CString, ACCOUNT_ENCFILE>  & mapAccountEncFile) 

    AddEncFile(AccountEncFile, arrayEncFile); 
    mapAccountEncFile[AccountEncFile.arrayUserAccount] = AccountEncFile;