2009-12-10 4 views
0

Je tente d'aborder la feuille de travail collégiale sur la programmation C (pas de marquage pour cela, juste pour améliorer notre apprentissage). Ce que nous sommes censés faire, c'est obtenir quelques détails sur les quais d'expédition. J'ai décidé d'utiliser des structures pour cela.Problèmes avec des structures avec des pointeurs vers des tableaux d'autres structures en C

Mon code est ci-dessous, ce que j'ai besoin d'aide est d'imprimer les informations (pour voir si cela fonctionne) de quoi à l'emplacement des chantiers navals .run. Tout se compile et selon le débogueur shipyard1.run et shipyard2.run pointent vers des emplacements différents, mais je ne peux pas voir les valeurs.

int main(int argc, char** argv) 
{ 
    typedef struct dockInfo 
    { 
     int dockCode; 
     int dockLength; 
    }dckDetails; 

    typdef struct shipyard 
    { 
     char dockName[20]; 

     /* however big this number is thats how many dockInfo structs are needed.*/ 

     int numOfDocks;    
     dckDetails *run; //points to the array of dockInfo structs 

    }; 

    struct dockInfo *arrayD; // the array to hold all the dockInfo structs 
    struct dockInfo tempo; // the temporary dockInfo struct to take in the details 
    struct shipyard shipyard1; 
    struct shipyard shipyard2; 

    /** 
    * the variables for shipyard1 and shipyard2 are then assigned 
    **/ 

    int i; 
    for (i=0;i<shipyard1.numOfDocks;i++) 
    { 

    arrayD=calloc(shipyard1.numOfDocks,100); // allocate a new bit of memory for arrayD 
    tempo.dockCode=45*i; 
    tempo.dockLength=668*i; 
    arrayD[i]=tempo; //the element of arrayD becomes tempo. 

    } 
    shipyard1.run=arrayD; //make shipyard1.run point to the location of arrayD. 

    for (i=0;i<shipyard2.numOfDocks;i++) 
    { 

    arrayD=calloc(shipyard2.numOfDocks,100); // allocate a new bit of memory for arrayD 
    tempo.dockCode=1234*i; 
    tempo.dockLength=1200*i; 
    arrayD[i]=tempo; //the element of arrayD becomes tempo. 

    } 
    shipyard2.run=arrayD; //make shipyard2.run point to the new location of arrayD. 

    int elementTest1; // need element1test to be shipyard1.run[0].dockLength; 
    int elementTest2; // need element2test to be shipyard2.run[1].dockCode; 

return (EXIT_SUCCESS); 
} 

Il convient de noter que je l'ai laissé beaucoup de code parce que je n'ai pas encore écrire. J'ai utilisé des exemples statiques pour l'instant (shipyard1 et shipyard2) mais dans le futur je vais implémenter une fonction 'load info from file'.

Toute aide serait grandement appréciée et s'il vous plaît excusez mon anglais s'il est pauvre, l'anglais n'est pas ma langue maternelle.

+0

Pourquoi déclarez-vous struct typedefs dans le corps de votre fonction principale? –

+0

... et pourquoi déclarez-vous un typedef et ne l'utilisez pas? –

+0

J'ai pris tous les commentaires et mis à jour mon code mais je ne sais toujours pas comment récupérer les valeurs des pointeurs shipyard.run. Par exemple, j'ai besoin d'obtenir la valeur dans shipyard1.run [0] .dockLength et shipyard2.run [1] .dockCode. J'ai essayé de faire 'elementTest1 = shipyard1.run [0] .dockLength;' mais j'ai une erreur ': erreur de déréférencement du type incomplet' dans la compilation. –

Répondre

3

Vous avez calloc() dans une boucle for deux fois. Les deux fois, vous perdez l'adresse renvoyée.

for() { 
    addr = calloc(); 
    addr[i] = ... 
} 

la deuxième fois dans la boucle, la addr vous avez obtenu le premier temps est révolu (vous vous avez une fuite mémoire ), la valeur que vous sauvé, il est allé trop.

Déplacer la calloc() en dehors de la boucle ... et souvenez-vous free() la mémoire lorsque vous ne avez plus besoin

addr = calloc(); 
for() { 
    addr[i] = ... 
} 
free(addr); 
1

Quelques commentaires:

  • Les pièces d'allocation de mémoire avec calloc devrait se produire en dehors de la boucle. Vous l'allouez maintenant, puis vous en perdez la trace lors de l'itération suivante, car une nouvelle mémoire est allouée et affectée.
  • mémoire vous allouez doit être libre d quelque part avec free
  • shipyard1.numOfDocks (même pour shipyard2) est non initialisées lorsque vous l'utilisez, il peut être un nombre aléatoire (qui signifie que vous avez un nombre indéfini de boucle les itérations et alloue une quantité indéfinie de mémoire).

Bonne chance!

1

D'autres ont fait de très bons points, et vous devriez corriger votre code en fonction d'eux. Jusqu'à présent, personne ne semble avoir vu que l'appel à calloc() est faux. Au lieu de:

arrayD=calloc(shipyard1.numOfDocks,100); 

il devrait être:

arrayD = calloc(shipyard1.numOfDocks, sizeof *arrayD); 

Vous voulez shipyard1.numOfDocks objets, chacun d'une taille égale à sizeof *arrayD.

En fait, comme mentionné ci-dessous, vous n'avez pas besoin de mettre la mémoire allouée à tous les zéros, de sorte que vous pouvez remplacer par calloc()malloc():

arrayD = malloc(shipyard1.numOfDocks * sizeof *arrayD); 

(Assurez-vous de #include <stdlib.h>, si vous appelez . calloc() ou malloc())

J'ai quelques sur le style commentaires mineurs:

  1. vous n'avez pas besoin de typedef. Vous pouvez écrire struct dockInfo au lieu de dckDetails. Si vous conservez le typedef, vous devez être cohérent et utiliser le nom typedef partout. Vous utilisez struct dockInfo la plupart du temps, puis utilisez dckDetails une fois. Votre utilisation suggère que vous n'étiez probablement pas à l'aise de déclarer un pointeur sur le struct. Cependant, struct dockInfo *run est une déclaration complètement valide.
  2. vous n'avez pas besoin de l'objet tempo. Vous pouvez à la place: arrayD[i].dockCode = 45*i; arrayD[i].dockLength = 668*i;
  3. Sauf si vous exécutez C99, vous ne pouvez pas déclarer des variables après des instructions dans un bloc. Vous devez donc déplacer les déclarations pour elementTest1 et elementTest2 vers le haut de , avec d'autres déclarations.
  4. return est une instruction, pas une fonction, donc les parenthèses ne sont pas nécessaires.
  5. Étant donné que vous remplacez immédiatement la mémoire allouée et que vous n'en avez pas besoin, vous pouvez remplacer calloc() par un appel approprié à malloc().

Comme je l'ai dit, ce sont des commentaires mineurs. Vos principaux problèmes résident dans l'utilisation erronée de calloc, etc.

+0

J'ai pris tous les commentaires et mis à jour mon code mais je ne sais toujours pas comment récupérer les valeurs des pointeurs shipyard.run. Par exemple, j'ai besoin d'obtenir la valeur dans shipyard1.run [0] .dockLength et shipyard2.run [1] .dockCode. J'ai essayé de faire 'elementTest1 = shipyard1.run [0] .dockLength;' mais j'ai une erreur 'erreur: pointeur de déréférencement vers le type incomplet' dans la compilation –

0

J'ai raccourci les noms des variables et les ai réécrit pour faire ce que je pense qui vous intéresse. J'ai également ajouté l'affichage des adresses dans lesquelles les données sont stockées. Généralement, quand j'essaie de comprendre quelque chose dans le monde des tableaux et des pointeurs, je fais le cas simple - un tableau incorporé (mon yard1) et ensuite je fais le pointeur après (yard2, yard3) Vous noterez chaque ensemble de données a différents points de départ, deux ajoutent i pour chaque point, on multiplie par i pour chaque point.

#include <libc.h> 
#include <stdlib.h> 
#include <stdio.h> 
#define MAX_DOCKS 100 

int main(int argc, char** argv) 
{ 

    struct dock 
    { 
     int code; 
     int length; 
    }; 

    struct yard 
    { 
     char name[20]; 
     int numDocks;    
     struct dock arDocks[MAX_DOCKS]; //an array of dock structs 
    }; 

    struct yard_2 
    { 
     char name[20]; 
     int numDocks;    
     struct dock *run; //points to the array of dock structs 
    }; 

/* données dans la fonction principale */

struct dock *arrayD; // pointer to dock structs 
struct yard yard1; 
struct yard_2 yard2; 
struct yard_2 yard3; 

int i; 
char temp[] = "2 draY"; 
strcpy(yard2.name, temp); /* temp is only persistant in main... */ 
strcpy(yard1.name, "Yard 1"); 
strcpy(yard3.name, "3 y 3 a 3 r 3 d 3"); 
yard1.numDocks = MAX_DOCKS; /* or so I guess.. */ 
yard2.numDocks = MAX_DOCKS; /* or so I guess.. */ 
yard3.numDocks = MAX_DOCKS; /* or so I guess.. */ 


/* get some memory, init it to 0 */ 
arrayD = calloc(yard2.numDocks, sizeof(struct dock)); 
    /* connect to the yard2 struct via "run", a pointer to struct dock */ 
yard2.run = arrayD;  

/* without middleman... get more memory, init it to 0 */ 
yard3.run = calloc(yard3.numDocks, sizeof(struct dock)); 

/* at this point arrayD could be re-used to get another hunk.. */ 

/* remplir et données d'affichage .. */

for (i=0;i<yard1.numDocks;i++) 
    { 
    /* This sets all the memory for yard 1... */ 
yard1.arDocks[i].code = 45 + i; 
yard1.arDocks[i].length = 668 + i; 

/* so here are some ways to display the data */ 

    printf("%d, %d %x %d %x - ", 
     i, yard1.arDocks[i].code, &(yard1.arDocks[i].code), 
     (yard1.arDocks[i].length), &(yard1.arDocks[i].length)); 

    /* This sets the memory for yard 2... */ 
yard2.run[i].code = 45 * i; 
yard2.run[i].length = 668 * i; 

/* Display through a pointer to a calloc'ed array of structs is the 
same syntax as the embedded array of structs. The addresses of the 
array are completely different - 0xbffff704 vs 0x800000 on my Intel-based iMac... */ 

    printf("%d %x %d %x - ", 
     yard2.run[i].code, &(yard2.run[i].code), 
     yard2.run[i].length, &(yard2.run[i].length)); 

yard3.run[i].code = 100 + i; 
yard3.run[i].length = 2000 + i; 

/* see where second calloc got its memory... */ 

    printf("%d %x %d %x\n", 
     yard3.run[i].code, &(yard3.run[i].code), 
     yard3.run[i].length, &(yard3.run[i].length)); 
    } 

/* toutes les données remplis, plus des démos de comment le récupérer: */

printf("%s,  : 1\n", yard1.name); 
printf("%d,  : numOfDocs \n", yard1.numDocks); 
printf("0x%x,  : arDocks \n", yard1.arDocks); 


int elementTest1 = yard1.arDocks[0].length; 
int elementTest2 = yard1.arDocks[1].code; 
int elementTest3 = yard2.run[0].length; 
int elementTest4 = yard3.run[1].code; 

printf("elementTest1: yard1.arDocks[0].length %d\n", elementTest1); 
printf("elementTest2: yard1.arDocks[1].code %d\n", elementTest2); 
printf("elementTest3: yard2.run[0].length %d\n", elementTest3); 
printf("elementTest4: yard3.run[1].code; %d\n", elementTest4); 

for (i=0; i< yard2.numDocks; i++) { 
printf("%d %d %d _ ", i, yard2.run[i].length, yard2.run[i].code); 
printf(" %d %d \n", yard3.run[i].length, yard3.run[i].code); 
} 


return (EXIT_SUCCESS); 
} 

Voici une modification Exemple de la sortie, compilation/construction via cc, cmd ligne a.out:

Macintosh-6:interview Bill4$ cc 

dockyard.c Macintosh-6:interview 

Bill4$ a.out 

0 45 bffff6f8 668 bffff6fc - 0 800000 0 800004 - 100 800400 2000 800404 
1 46 bffff700 669 bffff704 - 45 800008 668 80000c - 101 800408 2001 80040c 
2 47 bffff708 670 bffff70c - 90 800010 1336 800014 - 102 800410 2002 800414 
: 
Yard 1,  : 1 
100,  : numOfDocs 
0xbffff6f8,  : arDocks 
elementTest1: yard1.arDocks[0].length 668 
elementTest2: yard1.arDocks[1].code 46 
elementTest3: yard2.run[0].length 0 
elementTest4: yard3.run[1].code; 101 
0 0 0 _ 2000 100 
1 668 45 _ 2001 101 
2 1336 90 _ 2002 102 
3 2004 135 _ 2003 103 
: 
99 66132 4455 _ 2099 199 

Macintosh-6:interview Bill4$ 
Questions connexes