Erreur de mémoire mais je trouve pas le bug

dybman Messages postés 2 Date d'inscription dimanche 1 juillet 2001 Statut Membre Dernière intervention 17 mai 2007 - 16 mai 2007 à 20:49
dybman Messages postés 2 Date d'inscription dimanche 1 juillet 2001 Statut Membre Dernière intervention 17 mai 2007 - 17 mai 2007 à 15:59
Voici le code qui pose problème:

Je pense que la valeur Key prend de trop grande valeur et fais un dépassement de mémoire tampon mais je trouve pas le bug.

Merci pour votre aide.

/* Hash.C */

#include <stdlib.h>

#include "hash.h"
#include "types.h"
#include "mboard.h"

/* Macros */

#define BCH(N)          (BchTable[(uint8)(N)])
#define CODE(A,B,C,D,N) ((((((BCH((A)*(N))<<8)|BCH((B)*(N)))<<8)|BCH((C)*(N)))<<8)|BCH((D)*(N)))

/* Types */

typedef struct {
   uint32 Lock;
   info   Info;
} entry;

/* Variables */

int HashDate, HashScheme;

int ReadHashTotal, ReadHashTrue;
int WriteHashTotal, WriteHashTrue;

uint64 HashKeyTable[SQUARE_NB][PIECE_NB];

int HashAge[4];

static int    HashBitNb, DateBitNb, DateSize, ClusterSize;
static uint32 HashSize;
static entry *HashTable;

static uint8  BchTable[256];
static uint8  BchSeed;

/* Prototypes */

static void   SetDate    (int Date);
static int    EntryAge   (int Date);

static void   InitRandom (void);
static uint64 Rand64     (void);

/* Functions */

/* InitHash() */

void InitHash(void) {

   int S, P;

   HashBitNb = 20;
   HashSize  = 1 << HashBitNb;

   ClusterSize = 4;

   HashTable = malloc((HashSize+ClusterSize-1)*sizeof(entry));
   assert(HashTable!=NULL);

   DateBitNb = 2;
   DateSize  = 1 << DateBitNb;

   SetDate(0);
   ClearHashTable();

   InitRandom();

   for (S = 0; S <= 50; S++) { /* 0 maps to 0 (side to move) */
      for (P = 0; P < PIECE_NB; P++) {
         HashKeyTable[Std2Sq[S]][P] = Rand64();
      }
   }
}

/* ClearHashTable() */

void ClearHashTable(void) {

   int I,N;
   entry *Entry;
   for (I = 0; I < HashSize+ClusterSize-1; I++) {
      Entry = &HashTable[I];
      Entry->Lock = 0x00000000;
      ClearInfo(&Entry->Info);
   }
}

/* ClearInfo() */

void ClearInfo(info *Info) {

   Info->Date  = HashDate;
   Info->Depth = 0;
   Info->Min   = FALSE;
   Info->Max   = FALSE;
   Info->Value = 0;
   Info->Start = 0;
   Info->End   = 0;
}

/* UpdateHash() */

void UpdateHash(void) {

   SetDate((HashDate+1)%DateSize);
}

/* SetDate() */

static void SetDate(int Date) {

   int D;

   assert(Date>=0&&Date<DateSize);

   HashDate = Date;
   for (D 0; D < DateSize; D++) HashAge[D] EntryAge(D);
}

/* EntryAge() */

static int EntryAge(int Date) {

   int Age;

   assert(Date>=0&&Date<DateSize);

   Age = HashDate - Date;
   if (Age < 0) Age += DateSize;

   return Age;
}

/* ReadHash() */

info *ReadHash(uint64 Key, int Depth) {

   uint32 Key0, Key1;
   entry *Entry, *End;
   info *Info;

   ReadHashTotal++;

   Key0 = Key >> 32;
   Key1 = (uint32) Key;

   Entry = &HashTable[Key0];
   End   = Entry + ClusterSize;

   do {
      if (Entry->Lock == Key1) {
         ReadHashTrue++;
         Info = &Entry->Info;
         Info->Date = HashDate;
         return Info;
      }
   } while (++Entry < End);

   return NULL;
}

/* WriteHash() */

info *WriteHash(uint64 Key, int Depth) {

   int Diff, Age, BestAge, BestDepth;
   uint32 Key0, Key1;
   entry *Entry, *End, *Best;
   info *Info;

   WriteHashTotal++;

   Key0 = Key >> 32;
   Key1 = (uint32) Key;

   Entry = &HashTable[Key0];
   End   = Entry + ClusterSize;

   BestAge = -1;

   do {

      if (Entry->Lock == Key1) {
         Info = &Entry->Info;
         Info->Date = HashDate;
         if (Info->Depth <= Depth) {
            WriteHashTrue++;
            return Info;
         }
         return NULL;
      }

      Age  = HashAge[Entry->Info.Date];
      Diff = BestAge - Age;
      if (Diff < 0 || (Diff == 0 && BestDepth > Entry->Info.Depth)) {
         Best      = Entry;
         BestAge   = Age;
         BestDepth = Best->Info.Depth;
      }

   } while (++Entry < End);

   WriteHashTrue++;

   Best->Lock = Key1;
   Info = &Best->Info;
   ClearInfo(Info);

   return Info;
}

/* HashKey() */

uint64 HashKey(const mboard *Board) {

   int S, P;
   uint64 Key;

   Key = 0ULL;

   S = 0; /* Turn */   P (Board->Colour WHITE) ? WHITE_MAN : BLACK_MAN;
   Key ^= HashKeyTable[S][P];

   for (S = S1; S <= S50; S++) {
      P = HashPiece(&Board->Square[S]);
      if (P != NO_PIECE) Key ^= HashKeyTable[S][P];
   }

   return Key;
}

/* HashPiece() */

int HashPiece(const msquare *Square) {

   int P;

   P = NO_PIECE;

   switch (Square->Colour) {
   case WHITE :
      P = (! Square->IsKing) ? WHITE_MAN : WHITE_KING;
      break;
   case BLACK :
      P = (! Square->IsKing) ? BLACK_MAN : BLACK_KING;
      break;
   }

   return P;
}

/* InitRandom() */

static void InitRandom(void) {

   int I, N;
   for (I 0, N 0x01; I < 256; I++) {
      BchTable[I] = N;
      if ((N += N) >= 0x100) N ^= 0x171;
   }
   BchTable[255] = 0; /* So that every value is used only once */

   BchSeed = 0;
}

/* Random64() */

static uint64 Rand64(void) {

   uint32 Key, Lock;

   BchSeed++; /* To avoid the 0 value */

   Key  = CODE(7,5,3,1,BchSeed) & (HashSize - 1);
   Lock = CODE(15,13,11,9,BchSeed);

   return (((uint64) Key) << 32) | (uint64) Lock;
}

/* End of Hash.C */

2 réponses

luhtor Messages postés 2023 Date d'inscription mardi 24 septembre 2002 Statut Membre Dernière intervention 28 juillet 2008 6
17 mai 2007 à 12:35
Bas a toi de regarder, mais des tests dans ton code la ou tu pense qu'il peut y avoir un pb, et fait des sorties sur la console pour savoir ou ya des pbs. On est pas mieux placé que toi pour débugger ton code. Tu peux utiliser des macros pour ca:

#include <stdio.h>
#include <windows.h>
#include <stdlib.h>

#define ASSERT(X) \
{ \
    if (!(X))\
    { \
        printf("Condition non verifiee (%s)  <%s> <ligne %d>\n", #X, __FILE__, __LINE__);\
        system("PAUSE");\
        exit(1);\
    } \
}

int main()
{
    ASSERT(5 < 4); // Evidemment, le test échoue. Donc un msg est affiché.

    printf("coucou"); // ligne non affichée
   
    system("PAUSE");
   
    return 0;
};

Donc tu places en haut de ton fichier, cette macro ASSERT(X) et tu fais des tests partout.
Quand ton programme marche, tu neutralises l'effet de la macro, on changeant sa définition:
#define ASSERT(X)

La macro sera donc vide, et aucun test ne sera généré.
0
dybman Messages postés 2 Date d'inscription dimanche 1 juillet 2001 Statut Membre Dernière intervention 17 mai 2007
17 mai 2007 à 15:59
voici l'adresse du site si quelqu'un souhaite m'aider:

http://perso.orange.fr/eddy.balavoine/VIRTUAL%20DRAUGHTS/index.htm

merci d'avance
0
Rejoignez-nous