2017-09-24 2 views
-1

Ayant une structure de ce type, comment une structure peut-elle être copiée dans une autre. J'ai déclaré Array first et Array second, puis j'ai initilisé les deux et mis des données différentes dans chacun d'eux. Puis, pour copier first à second J'ai essayé second = first mais cela ne fonctionne pas.C - Copier des structures avec des tableaux dynamiques

Comment puis-je le faire?

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


    ////////////////////////////////////// 

    typedef struct { 

     int group[8]; 
     uint64_t points; 

    } BestGroup; 

    ////////////////////////////////////// 

    typedef struct { 
     BestGroup *array; 
     size_t used; 
     size_t size; 
    } Array; 

    void initArray(Array *a, size_t initialSize) { 
     a->array = (BestGroup *)malloc(initialSize * sizeof(BestGroup)); 
     a->used = 0; 
     a->size = initialSize; 
    } 

    void insertArray(Array *a, int *group_add, uint64_t points_add) { 

     // a->used is the number of used entries, because a->array[a->used++] updates a->used only *after* the array has been accessed. 
     // Therefore a->used can go up to a->size 
     if (a->used == a->size) 
     { 
     a->size *= 2; 
     a->array = (BestGroup *)realloc(a->array, a->size * sizeof(BestGroup)); 
     } 

     int i; 
     for (i = 0; i < 8; i++) 
     { 
     a->array[a->used].group[i] = group_add[i]; 
     } 
     a->array[a->used].points = points_add; 
     a->used++; 
    } 

    void freeArray(Array *a) { 
     free(a->array); 
     a->array = NULL; 
     a->used = a->size = 0; 
    } 


    void CopyArray(Array *a, Array *b) 
    { 
     b = a; 
    } 

    int main() 
    { 
     Array first; 
     Array second; 

     int first_data[8] = {0, 1, 2, 3, 4, 5, 6, 7}; 
     int second_data[8] = {7, 6, 5, 4, 3, 2, 1, 0}; 

     initArray(&first, 2); 
     initArray(&second, 2); 

     insertArray(&first, first_data, 5); 
     insertArray(&first, first_data, 5); 
     insertArray(&first, first_data, 5); 

     insertArray(&second, second_data, 2); 

     /////////////////////////////////////////// 

     printf("Total Points: %" PRIu64 "\n", first.array->points); 
     printf("Number: %lu\n\n", first.used); 
     printf("\n"); 

     int i; 
     int j; 

     for (i = 0; i < first.used; i++) 
     { 

      printf("["); 

      for (j = 0; j < 8; j++) 
      { 
      if (j) printf(", "); 
      printf("%d", first.array[i].group[j]); 
      } 

      printf("]\n"); 
     } 

     //////////////////////////////////////////// 

     printf("\n"); 
     printf("Total Points: %" PRIu64 "\n", second.array->points); 
     printf("Number: %lu\n\n", second.used); 
     printf("\n"); 

     for (i = 0; i < second.used; i++) 
     { 

      printf("["); 

      for (j = 0; j < 8; j++) 
      { 
      if (j) printf(", "); 
      printf("%d", second.array[i].group[j]); 
      } 

      printf("]\n"); 
     } 

     ///////////////////////////////// 

     CopyArray(&first, &second); 


     printf("\n"); 
     printf("\n"); 
     printf("\n"); 
     printf("\n"); 

     /////////////////////////////////////////// 

     printf("Total Points: %" PRIu64 "\n", first.array->points); 
     printf("Number: %lu\n\n", first.used); 
     printf("\n"); 

     for (i = 0; i < first.used; i++) 
     { 

      printf("["); 

      for (j = 0; j < 8; j++) 
      { 
      if (j) printf(", "); 
      printf("%d", first.array[i].group[j]); 
      } 

      printf("]\n"); 
     } 

     //////////////////////////////////////////// 

     printf("\n"); 
     printf("Total Points: %" PRIu64 "\n", second.array->points); 
     printf("Number: %lu\n\n", second.used); 
     printf("\n"); 

     for (i = 0; i < second.used; i++) 
     { 

      printf("["); 

      for (j = 0; j < 8; j++) 
      { 
      if (j) printf(", "); 
      printf("%d", second.array[i].group[j]); 
      } 

      printf("]\n"); 
     } 

     return 0; 
    } 

La sortie est:

Total Points: 5 
Number: 3 


[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 

Total Points: 2 
Number: 1 


[7, 6, 5, 4, 3, 2, 1, 0] 




Total Points: 5 
Number: 3 


[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 

Total Points: 2 
Number: 1 


[7, 6, 5, 4, 3, 2, 1, 0] 

Quand il doit se terminer par la dernière liste que:

Total Points: 5 
Number: 3 


[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 

Total Points: 5 
Number: 3 


[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 

EDIT

Comme suggéré je memcpy(), donc j'ai changé la fonction CopyArray() pour:

void CopyArray(Array *a, Array *b) 
    { 
     // b = a; 
     memcpy(b, a, a->size * sizeof(BestGroup)); 
    } 

Il semble que le résultat va bien, jusqu'à ce qu'il atteigne la fin du programme et les sorties

*** stack smashing detected ***

+0

Où est la ligne correspondante dans le code ci-dessus? Cela devrait fonctionner s'ils ont le même type (Vous pouvez essayer memcpy() comme déjà suggéré). –

+1

La majorité du code que vous avez présenté ne semble pas pertinent à la question. Nous aimons voir du code, mais généralement nous voulons un [mcve], avec emphase, dans ce cas, sur "* minimal *". Mais ne négligez pas "complet". Ce n'est pas clair ce que "ça ne marche pas" signifie ici, ou comment vous déterminez cela. En particulier, vous pouvez absolument utiliser l'opérateur '=' pour copier la valeur d'une structure entière dans une autre structure du même type. –

+0

Juste ajouté la fonction principale à la question ainsi que les deux sorties réelles et attendues – PyCV

Répondre

1

Ce code produit la réponse que vous voulez. La fonction CopyArray() libère maintenant les données déjà dans b, puis initialise b, et enfin copie les données de a à b. Il y a des endroits où le code utilise 8 mais devrait probablement utiliser une variable différente pour la taille - je les ai annotés dans ce code. La fonction dump_array() est un exemple d'une fonction que j'écris couramment et que j'utilise lors du débogage d'une structure complexe. Il prend une chaîne d'étiquette (qui vous permet d'identifier quel appel est en cours d'impression) plus l'objet à imprimer. Je prends souvent un argument de flux de fichier aussi, et en cas de doute, ajouter un fflush() pour le flux de sortie.

/* SO 4639-4467 */ 
#include <inttypes.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

typedef struct 
{ 
    int group[8]; 
    uint64_t points; 
} BestGroup; 

typedef struct 
{ 
    BestGroup *array; 
    size_t used; 
    size_t size; 
} Array; 

static void initArray(Array *a, size_t initialSize) 
{ 
    a->array = (BestGroup *)malloc(initialSize * sizeof(BestGroup)); 
    a->used = 0; 
    a->size = initialSize; 
} 

static void insertArray(Array *a, const int *group_add, uint64_t points_add) 
{ 
    if (a->used == a->size) 
    { 
     a->size *= 2; 
     a->array = (BestGroup *)realloc(a->array, a->size * sizeof(BestGroup)); 
    } 

    for (int i = 0; i < 8; i++)  // Why 8 and not points_add? 
    { 
     a->array[a->used].group[i] = group_add[i]; 
    } 
    a->array[a->used].points = points_add; 
    a->used++; 
} 

static void freeArray(Array *a) 
{ 
    free(a->array); 
    a->array = NULL; 
    a->used = a->size = 0; 
} 

static void CopyArray(const Array *a, Array *b) 
{ 
    freeArray(b); 
    initArray(b, a->used); 
    memmove(b->array, a->array, a->used * sizeof(a->array[0])); 
    b->used = a->used; 
} 

static void dump_array(const char *tag, const Array *arr) 
{ 
    printf("Array: %s\n", tag); 
    printf("Total Points: %" PRIu64 "\n", arr->array->points); 
    printf("Number: %lu\n", arr->used); 

    for (size_t i = 0; i < arr->used; i++) 
    { 
     printf("["); 
     for (size_t j = 0; j < 8; j++) // Why 8 and not arr->array[i].points? 
     { 
      if (j) 
       printf(", "); 
      printf("%d", arr->array[i].group[j]); 
     } 
     printf("]\n"); 
    } 
    putchar('\n'); 
} 

int main(void) 
{ 
    Array first; 
    Array second; 

    int first_data[8] = {0, 1, 2, 3, 4, 5, 6, 7}; 
    int second_data[8] = {7, 6, 5, 4, 3, 2, 1, 0}; 

    initArray(&first, 2); 
    initArray(&second, 2); 

    insertArray(&first, first_data, 5); 
    insertArray(&first, first_data, 5); 
    insertArray(&first, first_data, 5); 
    insertArray(&second, second_data, 2); 

    dump_array("first", &first); 
    dump_array("second", &second); 

    CopyArray(&first, &second); 

    printf("\n"); 
    dump_array("first", &first); 
    dump_array("second", &second); 

    return 0; 
} 

La sortie de l'exécution de c'est la suivante:

Array: first 
Total Points: 5 
Number: 3 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 

Array: second 
Total Points: 2 
Number: 1 
[7, 6, 5, 4, 3, 2, 1, 0] 


Array: first 
Total Points: 5 
Number: 3 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 

Array: second 
Total Points: 5 
Number: 3 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7] 
[0, 1, 2, 3, 4, 5, 6, 7]