1

因为我们需要从 VB6 调用下面的代码,所以我们必须将方法的签名从

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

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

ddTableDeal 结构仅包含一个 16 字节的数组,而 ddTableResults 结构仅包含一个 20 字节的数组,并填充了 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 次迭代后因内存不足异常而死机。这可能是由签名更改引起的吗?对我们来说,这似乎不太可能,因为 150,000 乘以 36 字节刚好超过 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 回答