2011-03-04 3 views
1

Je génère des tableaux 2d contigus en utilisant la méthode affichée ici par Shawn Chin. [1] [2] Il fonctionne très bien.Réallocation d'un tableau 2D contigu

brièvement de son poste:

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 libre suivante:

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

Il me est pas évident de comment créer une fonction de réallouer équivalente dans les deux dimensions, bien que je ne suis intéressé à réallouer 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 de cette question ailleurs que pour dire: «c'est dur!». [2] Bien sûr, cela est possible 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éallouant le tableau 1D, puis en libérant et en régénérant les pointeurs (ptr_array) vers le éléments de ligne pour la nouvelle taille. Ceci, cependant, est assez lent pour les modifications de ligne, car il est nécessaire de doubler au moins la mémoire requise pour copier les données, et c'est vraiment horriblement mauvais pour changer le nombre de colonnes. Ceci est un exemple de ladite 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 erronés pour les données). Je ne l'ai pas entièrement testé, 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 de connaître la taille précédente, ce qui est désagréable!

Toute pensée grandement appréciée.

[1] How can I allocate a 2D array using double pointers?

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

Répondre

2

Le premier malloc et memcpy ne sont pas nécessaires, parce que vous avez un accès facile à l'ensemble de données d'origine à ptr_array[0]. Vous n'avez pas besoin de connaître l'ancienne taille, car realloc doit rappeler combien il a alloué à l'adresse et déplacer le nombre correct de données.

Quelque chose comme ça devrait fonctionner.

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; 
} 
+0

Merci beaucoup. Ceci est correct et fonctionne bien. – coastal