0

DLL のメソッドを呼び出す EXE があります。

DLL のメソッドは次のように定義されます。CSimpleArray は ATL クラスです。

class DriverUtility
{
    ....
    virtual bool GetFlagsOfRun(int runID, CSimpleArray<FlagData> &flags) = 0;
};

struct FlagData
{
    CString Name;
    CString Value;
    CString TypeName;
};

EXEでメソッドを次のように呼び出します

CSimpleArray<FlagData> m_mdFlags;
m_pDriverUtility->GetFlagsOfRun(m_lRunID, m_mdFlags);

m_mdFlags.RemoveAll を呼び出すと、次の場所free(m_aT);でヒープ エラーでクラッシュします。

void RemoveAll()
   {
          if(m_aT != NULL)
          {
                 for(int i = 0; i < m_nSize; i++)
                       m_aT[i].~T();
                 free(m_aT);
                 m_aT = NULL;
          }
          m_nSize = 0;
          m_nAllocSize = 0;
}

ヒープにメモリを割り当てるときは、ローカルで割り当てを解除する必要があることを理解しています。呼び出し元 (EXE) でオブジェクトを作成し、呼び出し元から RemoveAll() も呼び出しているため、ここで何が問題なのかわかりません。

4

1 に答える 1

0

メソッド自体は配列をコピーせず、原因となる可能性は低いです(ただし、他の偶発的なエラーから保護されないという点で、私には安全に見えません)。

配列要素で渡された構造から文字列をコピーしている可能性があり、最終的にはDLLおよびEXEモジュールの文字列アロケータが混乱し、アクセス違反が発生する可能性があります。呼び出し元がその文字列をコピーしないようにしてください。コピーを作成する必要がある場合は、次のようにします。

GetFlagsOfRun(..., flags) {
  FlagData& a = ...
  CString b = (LPCTSTR) a.Name; // Not a.Name directly!
  ...
}
于 2012-12-11T09:04:32.373 に答える