2010-08-18 6 views
1

Qu'est-ce que je fais mal ici?Comment puis-je retourner un pointeur sur un élément dans un tableau de structures?

/* 
* Consider the following pseudo code ! 
*/ 
typedef struct foobar { 
    unsigned char id, count; 
    struct foobar *child; 
} foobar; 

foobar root = (foobar *) malloc(sizeof(struct foobar)); 
root->child = (foobar *) malloc(sizeof(struct foobar)); 

root->count++; 
root->child[0].id = 1; 

root->count++; 
root->child[1].id = 2; 

root->count++; 
root->child[3].id = 3; 

root->child[0].child = (foobar *) malloc(sizeof(struct foobar)); 

root->child[0].child[0].count++; 
root->child[0].child[0].id = 4; 

root->child[1].child = (foobar *) malloc(sizeof(struct foobar)); 
root->child[0].child[0].count++; 
root->child[1].child[0].id = 5; 

root->child[0].child[0].count++; 
root->child[1].child[1].id = 6; 

/* and so on */ 

/* 
* Function to search for an ID inside the tree, 
* it should call itself in order to go deeper into 
* the childs, but taht's not implemented here 
*/ 
foobar *search(unsigned char id, foobar *start_node = NULL); 
foobar *search(unsigned char id, foobar *start_node) { 
    if(start_node == NULL) { 
     unsigned char x; 
     for(x = 0; x < root->count; x++) { 
      if(root->child[ x ].id == id) { 
       foobar *ptr = &root->child[ x ]; 
       /* If I call ptr->id now, it will return the correct value */ 
       return &ptr; 
      } 
     } 

    } else { /* not implemented */ } 
} 

/* Search the array for and ID */ 
foobar **ptr = this->search(1); 
/* If I call ptr->id now, it will return memory garbage */ 

Répondre

1

je faisais une ou deux choses mal .. dans le code ci-dessus les lignes:

foobar *ptr = &root->child[ x ]; 
return &ptr; 

doit être changé simplement return &root->child[ x ];, cela renvoie un pointeur vers la adr mémoire de root->child[ x ].

La ligne foobar **ptr = this->search(1); deviendra foobar *ptr = this->search(1);, ce qui permettra d'accéder aux propriétés de structure en utilisant le caractère .; -> ne peut pas être utilisé et sortira des ordures. Exemple d'utilisation correct: (*ptr).description. Merci à adamk!

+0

Vous vous trompez - '(* ptr) .description' est * exactement le même * que' ptr-> description'. – caf

1

Vous renvoyez l'adresse du pointeur que vous avez récupéré. Vous devriez retourner le pointeur lui-même.

1

Vous ne disposez que d'une mémoire malloc pour un enfant, mais essayez de définir l'ID pour 4 enfants maximum.

Il devrait ressembler à ceci:

root->child = (foobar *) malloc(sizeof(struct foobar) * 4); 
2

racine a 4 enfants (comme vous accédez root-> enfant [3]), vous devez donc allouer suffisamment de mémoire:

root->child = (foobar *) malloc(sizeof(struct foobar) * 4); //at least 4 

En outre, vous devez retourner le pointeur foobar lui-même, et non un pointeur (par exemple return ptr; au lieu de return &ptr;

+0

J'ai corrigé le code et maintenant je ne retourne que "return ptr"; la mémoire est encore garbaged. Comment puis-je retourner un pointeur valide pointant vers l'adresse mémoire de root-> child [x] afin qu'il puisse être utilisé plus tard en dehors de la fonction. L'ideia est de faire une recherche pour l'id et retourne l'objet qui contient cet id. – Joao

+0

Avez-vous pensé à changer 'foobar ** ptr = this-> search (1);' à 'foobar * ptr = this-> search (1);' aussi? – adamk

+0

Oui .. a également fait cela. Je suis très newb en C mais si une fonction retourne un pointeur vers l'adresse mémoire de root-> child [x] (root est un var au niveau global), l'addr mémoire serait valide soit à l'intérieur ou à l'extérieur de la fonction. correct ? – Joao

1

Vous renvoyez l'adresse d'une variable locale à partir de la fonction search (return &ptr;). Cet objet sera détruit dès que la fonction search sera terminée. Essayer d'utiliser cet emplacement de mémoire à l'extérieur de la fonction entraînera un comportement indéfini.

+0

J'ai corrigé le code et maintenant je ne retourne que "return ptr"; la mémoire est encore garbaged. Comment puis-je retourner un pointeur valide pointant vers l'adresse mémoire de root-> child [x] afin qu'il puisse être utilisé plus tard en dehors de la fonction. L'idée est de faire une recherche pour l'ID et retourner l'objet qui contient cet ID. – Joao

Questions connexes