1

以下のコードを VB6 から呼び出す必要があるため、メソッドのシグネチャを から変更する必要がありました。

int STDCALL CalcDDtable(struct ddTableDeal tableDeal, struct ddTableResults * tablep

int STDCALL CalcDDtable(struct ddTableDeal * tableDeal, struct ddTableResults * tablep

ddTableDeal 構造体には 16 バイトの配列のみが含まれ、ddTableResults 構造体には 20 バイトの配列が 1 つだけ含まれ、dll の計算結果が格納されます。

コードは次のように VB6 から呼び出されます。

Declare Function CalcDDtable Lib "dds222vb6.dll" (ByRef lngDeal As Long, ByRef lngResult As Long) As Long
Dim Cards(15) As Long   
Dim Results(19) As Long
'Some code to populate the Cards array. The Results arrays contains zeroes.
lngErrorCode = CalcDDtable(Cards(0), Results(0)) 

ただし、テスト コンピューターは、150,000 回の反復後にメモリ不足の例外でフリーズします。これは署名の変更によって引き起こされる可能性がありますか? 私たちにとっては、36 バイトの 150,000 倍が 5MB 強のメモリに相当することはありそうにありません。

完全な (調整された) コード。唯一の変更点は署名であり、それddTableDeal.cardsは で変更されていddTableDeal->cardsます。

int STDCALL CalcDDtable(struct ddTableDeal * tableDeal, struct ddTableResults * tablep) {

  int h, s, k, ind, tr, first, res;
  struct deal dl;
  struct boards bo;
  struct solvedBoards solved;

  for (h=0; h<=3; h++)
    for (s=0; s<=3; s++)
      dl.remainCards[h][s]=tableDeal->cards[h][s];

  for (k=0; k<=2; k++) {
    dl.currentTrickRank[k]=0;
    dl.currentTrickSuit[k]=0;
  }

  ind=0; bo.noOfBoards=20;

  for (tr=4; tr>=0; tr--) 
    for (first=0; first<=3; first++) {
      dl.first=first;
      dl.trump=tr;
      bo.deals[ind]=dl;
      bo.target[ind]=-1;
      bo.solutions[ind]=1;
      bo.mode[ind]=1;
      ind++;
    }

  res=SolveAllBoards4(&bo, &solved);
  if (res==1) {
    for (ind=0; ind<20; ind++) {
      tablep->resTable[bo.deals[ind].trump][rho[bo.deals[ind].first]]=
        13-solved.solvedBoard[ind].score[0];
    }
    return 1;
  }

  return res;
}
4

1 に答える 1

2

CalcDDtable の関数シグネチャはメモリ リークを起こしません。関数 CalcDDtable のコードには、関数が呼び出されたときにスタックに割り当てられ、関数が戻るときにスタックからポップされるローカル変数がいくつかあります。したがって、メモリリークはこの関数にはありません。

于 2012-10-26T06:43:04.483 に答える