2010-11-22 3 views
1

gcc 4.4.5 C89mémoire allouée libération

J'ai une fonction appelée create_object où j'allouer de la mémoire pour une structure globale. Et j'ai une fonction appelée destroy_object où je vérifie que le pointeur n'est pas nul, alors je suis libre. Juste au cas où je libère de la mémoire qui n'a pas été allouée. Cependant, j'ai testé cela en effectuant 2 appels consécutifs à destroy_object. Cependant, j'obtiens un vidage de pile au deuxième appel. Cependant, je suis sûr qu'il ne serait pas libre car j'ai assigné le pointeur à NULL. Donc, il devrait ignorer la fonction gratuite.

static struct Config_t { 
    char protocol[LINE_SIZE]; 
    char mode[LINE_SIZE]; 
} *app_cfg = NULL; 

int create_object() 
{ 
    app_cfg = malloc(sizeof *app_cfg); 
    memset(app_cfg, 0, sizeof *app_cfg); 
} 

void destroy_config() 
{ 
    /* Check to see if the memory is ok to free */ 
    if(app_cfg != NULL) { 
     free(app_cfg); 
     app_cfg = NULL; 
    } 
} 

Un grand merci pour toutes les suggestions,

================= ========== EDIT Basicially J'ai en Ma fonction principale est un appel à create_object() et je fais un traitement, puis je fais un appel à destory_object.

int main(void) 
{ 
    create_object(); 

    /* Do some processing on the structure */ 

    destroy_object(); 

    return 0; 
} 

========================= final Edit ==== statique struct {Config_t protocole char [LINE_SIZE]; mode char [LINE_SIZE]; } app_cfg [1] {{"", ""}};

Et maintenant je n'utilise pas malloc et gratuit.

+1

Cela me semble bien, pouvez-vous poster le code qui utilise ce pointeur et fait des appels à 'create_object' et' destroy_config'? De plus, si vous voulez initialiser immédiatement votre mémoire allouée à 'app_cfg' à 0s, vous pouvez combiner vos appels' malloc' et 'memset' en un seul appel' calloc'. De même, 'free' sur un pointeur nul est parfaitement correct. – birryree

+1

Passer un pointeur null à 'free()' est un no-op sûr, donc vous n'avez pas besoin de la vérification null dans 'destroy_config()'. – Wyzard

+2

êtes-vous en mesure d'exécuter le code via gdb et regarder le backtrace après que le SIGSEGV est soulevée? Indique-t-il un autre endroit dans votre programme? – vpit3833

Répondre

3

Je n'ai qu'une suggestion. Ne pas allouer de la mémoire pour cela, c'est une perte d'effort. Puisque app_cfg est une variable de niveau fichier, vous ne pouvez en avoir qu'une copie à la fois, il est donc inutile de l'allouer et de la désallouer.

Il suffit de le créer comme non-pointeur et de l'utiliser statique:

static struct Config_t { 
    char protocol[LINE_SIZE]; 
    char mode[LINE_SIZE]; 
} app_cfg; 

Vous pouvez fournir encore un create et destroy qui memset la structure de zéros, mais même cela peut ne pas être nécessaire:

void create_object (void) { 
    memset(&app_cfg, 0, sizeof(app_cfg)); 
} 

void destroy_config (void) { 
    memset(&app_cfg, 0, sizeof(app_cfg)); 
} 
+0

'memset' n'est définitivement pas nécessaire.Il est garanti d'être rempli de 0, car il est statique. Et détruire ne semble pas avoir de sens non plus. –

+0

@Matthew, je pensais plutôt au cas où vous vouliez qu'il soit effacé avant la réutilisation plutôt que l'utilisation initiale. Mais, même s'il n'est pas autorisé à créer/détruire, les codeurs décents ne devraient pas écrire du code affecté par les valeurs qui traînent, d'où mon commentaire "peut ne pas être nécessaire". – paxdiablo

+0

J'ai changé mon code source et fait ce que vous avez suggéré. Juste une question. Dans mon code source, je n'aurai besoin que d'une copie de la variable struct (niveau de pile, static global). Je suppose que si je créais beaucoup d'objets de cette structure et que je voulais qu'ils soient disponibles pour la durée de vie de l'application. Je suppose que c'est une bonne raison d'utiliser malloc? – ant2009

2

en utilisant ce code avec gcc 3.3.3 sous Cygwin fonctionne correctement pour moi quand je l'appelle deux fois. Vous ne nous avez pas dit ce que vous faites en dehors de ces fonctions, alors regardez d'abord, par exemple. peut-être que vous attribuez accidentellement une valeur non nulle NULL à app_cfg entre les appels. De plus, si vous n'utilisez pas un compilateur "big-name", il est possible que ce soit un bogue du compilateur (par exemple, il peut être trop optimiste au moment de la compilation et supposer que vous ne passerez jamais une valeur NULL à destroy_config). Essayez de mettre quelque chose comme:

void destroy_config() 
{ 

    /* Check to see if the memory is ok to free */ 
    if(app_cfg != NULL) { 
     printf("not null\n"); 
     free(app_cfg); 
     app_cfg = NULL; 
    }else{ 
     printf("null\n"); 
     } 
} 

pour voir si c'est vraiment "savoir" quand c'est nul.

+0

Il n'y a rien de mal à libérer 'NULL', donc ce n'est pas la source du bug. En outre, ce n'est certainement pas un bug de compilateur. –

Questions connexes