Réallocation de tableau 2D contigu

Je génère des tableaux 2D contigus en utilisant la méthode décrite ici par Shawn Chin. [1] [2] Il fonctionne très bien.

En bref de son post:

char** allocate2Dchar(int count_x, int count_y) { int i; # allocate space for actual data char *data = malloc(sizeof(char) * count_x * count_y); # create array or pointers to first elem in each 2D row char **ptr_array = malloc(sizeof(char*) * count_x); for (i = 0; i < count_x; i++) { ptr_array[i] = data + (i*count_y); } return ptr_array; } 

Et la fonction gratuite suivante:

 void free2Dchar(char** ptr_array) { if (!ptr_array) return; if (ptr_array[0]) free(ptr_array[0]); free(ptr_array); } 

Il n’est pas évident pour moi de créer une fonction de réallocation équivalente dans l’une ou l’autre des dimensions, bien que mon intérêt soit uniquement de réaffecter le nombre de lignes tout en maintenant la continuité. Augmenter le nombre de colonnes serait intéressant à comprendre mais probablement assez difficile. Je n’ai trouvé aucune discussion directe sur cette question ailleurs que de dire «c’est difficile!». [2]

Bien sûr, cela est faisable par une méthode de force brute horrible, en copiant les données dans un nouveau tableau 1D (données, ci-dessus) pour le stockage, en réaffectant le tableau 1D, puis en libérant et en régénérant les pointeurs (ptr_array) sur les éléments nouvelle taille. Toutefois, cela est assez lent pour les modifications de lignes, car il faut au moins doubler la mémoire requirejse pour copier les données, ce qui est terriblement mauvais pour changer le nombre de colonnes.

Ceci est un exemple de cette méthode pour changer le nombre de lignes (cela ne fonctionnerait pas correctement pour changer le nombre de colonnes car les décalages pour les pointeurs seraient incorrects pour les données). Je n’ai pas complètement testé cela, mais vous voyez l’idée …

 double ** reallocate_double_array (double **ptr_array, int count_row_old, int count_row_new, int count_col) { int i; int old_size = count_row_old * count_col; int new_size = count_row_new * count_col; double *data = malloc (old_size * sizeof (double)); memcpy (&data[0], &ptr_array[0][0], old_size * sizeof (double)); data = realloc (data, new_size * sizeof (double)); free (ptr_array[0]); free (ptr_array); ptr_array = malloc (count_row_new, sizeof (double *)); for (i = 0; i < count_row_new; i++) ptr_array[i] = data + (i * count_col); return ptr_array; } 

De plus, cette méthode nécessite que vous connaissiez la taille précédente, ce qui est odieux!

Toute pensée grandement appréciée.

[1] Comment puis-je allouer un tableau 2D en utilisant des pointeurs doubles?

[2] http://www.eng.cam.ac.uk/help/tpl/languages/C/teaching_C/node52.html

Le premier malloc et le memcpy sont inutiles, car vous avez un access facile au tableau de données d’origine à ptr_array[0] . Vous n’avez pas besoin de connaître l’ancienne taille, car realloc doit rappeler le montant alloué à l’adresse et déplacer la quantité de données correcte.

Quelque chose comme ça devrait marcher.

 double ** reallocate_double_array (double **ptr_array, int count_row_new, int count_col) { int i; int new_size = count_row_new * count_col; double *data = ptr_array[0]; data = realloc (data, new_size * sizeof (double)); free (ptr_array); ptr_array = calloc (count_row_new, sizeof (double *)); for (i = 0; i < count_row_new; i++) ptr_array[i] = data + (i * count_col); return ptr_array; }