// Taille du tampon anti-overflow (en octets)
#define TAILLE_TAMPON_OVERFLOW 16

// Nombres magiques (32 bits) pour valider un pointeur
#define MALLOC_NBR_MAGIQUE 0x1A71A25C

// Allocation de mémoire sécurisée (malloc)
void* MallocSecurise (size_t size, const char *nomfich, unsigned long numligne)
{
  // Tente d'allouer le tampon
  void* ptr;
  size_t taille_allouee;
  InfoMalloc *info;
  char *overflow;
  unsigned long i;
  unsigned char rand = 0xA0;

  // Taille nulle : Erreur!
  if (size == 0) ERREUR ("Taille du pointeur à allouer nulle !");

  // Ajoute la taille des informations sur le pointeur
  taille_allouee = size +sizeof(InfoMalloc) +TAILLE_TAMPON_OVERFLOW;

  // Alloue la mémoire (appelle le malloc du langage C)
  ptr = malloc(taille_allouee);

  // Pointeur NULL : erreur!
  if (ptr == NULL)
    ERREUR ("Allocation de mémoire impossible : pas assez de mémoire libre !");

  // Ajoute le pointeur au conteneur
  info = (InfoMalloc *)ptr;
  CONTENEUR_MALLOC_AJOUTE (info);

  // Ecrit les informations sur le pointeur
  info -> nbr_magique = MALLOC_NBR_MAGIQUE;
  info -> est_alloue = true;
  info -> taille = taille_allouee;
  info -> nom_fich = nomfich;
  info -> num_ligne = numligne;
  info -> somme_info = MallocCalculSomme (info);

  // Prépare le tampon anti-overflow
  overflow = (char *)info +taille_allouee;
  for (i=0; i<TAILLE_TAMPON_OVERFLOW; i++) *ptr++ = rand++;

  // Renvoie le pointeur vers l'espace alloué vierge
  return (info+1);
}

// Calcule la somme de contrôle des informations d'un pointeur
ulong MallocCalculeSomme (const InfoMalloc *info)
{
  // Calcule la somme des données d'un pointeur
  return
   ((ulong)(info -> nbr_magique)
   +(ulong)(info -> est_alloue)
   +(ulong)(info -> taille)
   +(ulong)(info -> est_local)
   +(ulong)(info -> nom_fich)
   +(ulong)(info -> num_ligne));
}
