Allouer dynamiquement un tableau à n dimensions avec uniquement un malloc

Portrait de bruno

Voici le code de la fonction array_alloc qui perment d'allouer un tableau de dimention n.
Le premier argument qu'elle prend c'est le nombre de dimention du tableau.
Le deuxième c'est un tableau contenant la taille de chaque dimention.
Le dernier argument désigne la taille du type avec lequel on rempliera la tableau.

#define PTR_SIZE sizeof (void*)                                                                                                                                                                                     
 
void*                                                                                                                                                                                                               
array_alloc (int n, int tab[], size_t elemSize)                                                                                                                                                                     
{                                                                                                                                                                                                                   
  int i,j;                                                                                                                                                                                                          
  int pro;                                                                                                                                                                                                          
  int sum;                                                                                                                                                                                                          
  size_t dataSize;                                                                                                                                                                                                  
  size_t  blocSize = 0;                                                                                                                                                                                             
  void* ptrAlloc;                                                                                                                                                                                                   
 
  void *ptrBase, *ptrP;                                                                                                                                                                                             
 
  if (tab == NULL || n == 0 || elemSize == 0) {                                                                                                                                                                     
    return NULL;                                                                                                                                                                                                    
  }                                                                                                                                                                                                                 
  if (n == 1) {                                                                                                                                                                                                     
    return malloc (tab[0] * elemSize);                                                                                                                                                                              
  }                                                                                                                                                                                                                 
  sum = 0;                                                                                                                                                                                                          
  pro = 1;                                                                                                                                                                                                          
  for (i = 0; i < n - 1; i++){                                                                                                                                                                                      
    pro *= tab[i];                                                                                                                                                                                                  
    sum += pro;                                                                                                                                                                                                     
  }                                                                                                                                                                                                                 
 
  blocSize  = sum * PTR_SIZE + pro * elemSize * tab[i];                                                                                                                                                             
 
  if ((ptrAlloc = malloc (blocSize)) == NULL){                                                                                                                                                                      
      return NULL;                                                                                                                                                                                                  
  }                                                                                                                                                                                                                 
  ptrBase = ptrP = ptrAlloc;                                                                                                                                                                                        
  for (i = 0, pro = 1; i < n - 1; i++) {                                                                                                                                                                            
      pro *= tab[i];                                                                                                                                                                                                
      ptrBase += pro * PTR_SIZE;                                                                                                                                                                                    
      dataSize = (i == n - 2) ? elemSize : PTR_SIZE;                                                                                                                                                                
      for (j = 0; ptrP < ptrBase; ptrP += PTR_SIZE, j++) {                                                                                                                                                          
        *((void**)ptrP) = ptrBase + tab[i+1] * j * dataSize;                                                                                                                                                        
      }                                                                                                                                                                                                             
  }                                                                                                                                                                                                                 
  return ptrAlloc;                                                                                                                                                                                                  
}