2009-10-01 8 views
0

Je struct comme ceci:question simple pointeur imbriqué

struct Child 
{ 
    int foo; 
    char bar[42]; 
}; 

struct Parent 
{ 
    long foobar; 
    struct Child ** children; 
    size_t num_children; 
} 

J'ai défini une API comme ceci:

struct Parent * ParentAlloc() { struct Parent* ptr = (struct Parent*)calloc(1, sizeof(struct Parent)); 
ptr->children = (struct Child**)calloc(SOME_NUMBER, sizeof(struct Child*)); 
return ptr; 
} 

Maintenant, si je veux supprimer un (précédemment attribué) enfant - en supposant index n'est pas hors limites:

void FreeChild(struct Parent* parent, const size_t index) 
{ 
    free(parent->children[index]); 

    //now I want to mark the address pointed to in the array of pointers as null, to mark it as available 

    //I dont think I can do this (next line), since I have freed the pointer (its now "dangling") 
    parent->children[index] = 0; // this is not right. How do I set this 'freed' address to null ? 


} 

Répondre

0

Vous mélangez un tableau de pointeurs avec un tableau de structures. Enlevez l'étoile double et opérez sur les décalages:


... 
struct Parent 
{ 
    long foobar; 
    struct Child* kids; 
    size_t numkids; 
}; 
... 
struct Parent * ParentAlloc() 
{ 
    struct Parent* ptr = (struct Parent*)calloc(1, sizeof(struct Parent)); 
    ptr->kids = (struct Child*)calloc(SOME_NUMBER, sizeof(struct Child)); 
    ptr->numkids = SOME_NUMBER; /* don't forget this! */ 
    return ptr; 
} 
... 
struct Child* GetChild(struct Parent* p, size_t index) 
{ 
    assert(p); 
    assert(index < p->numkids); 
    return p->kids + index; 
} 
+0

Merci - beaucoup plus propre que mon code d'origine (bien que je sois assuré que c'était correct, je me suis trompé parce que je mélangeais un tableau de ptrs et un tableau de structures). Merci à tous ceux qui ont répondu. Infiniment reconnaissant – scoobydoo

2

Il n'y a pas de problème avec le réglage de la parent-> enfants [index] à NULL. Vous avez uniquement libéré la mémoire vers laquelle pointe le pointeur, et non la mémoire dans laquelle le pointeur est lui-même stocké.

2

Bien sûr, vous pouvez le faire. Un pointeur est une variable dont la valeur est une adresse. Il est parfaitement correct, en fait, de mettre en place des pointeurs sur 0 (ou NULL) après avoir appelé gratuitement, afin de pouvoir les vérifier pour être non nul et éviter les erreurs de segmentation. Bottom line: Votre code est correct.