2017-10-11 14 views
3

Je suis en train de libérer la mémoire du tableau alloué à l'intérieur struct _Stack, mais le programme se bloqueComment libérer une mémoire allouée dynamiquement à un tableau dans une structure?

typedef struct _Stack 
{ 
    int top; 
    unsigned int capacity; 
    int* arr; 
}_Stack; 

_Stack* createStack(int capacity) 
{ 
    _Stack* stack = (_Stack*) malloc(sizeof(_Stack)); 
    stack->capacity = capacity; 
    stack->top = -1; 
    stack->arr = (int*) malloc(sizeof(stack->capacity * sizeof(int))); 
    return stack; 
} 

J'utilise cette fonction pour libérer la mémoire, mais le programme se bloque ici.

// I have a problem here. 
void stack_free(_Stack* stack) 
{ 
    free(stack->arr); 
    free(stack); 
} 

Here's the error message

+5

Si vous programmez en C++, pourquoi utilisez-vous 'malloc' et' free'? Si vous devez utiliser des pointeurs, utilisez d'abord un * pointeur intelligent * comme par ex. ['std :: unique_ptr'] (http://en.cppreference.com/w/cpp/memory/unique_ptr), et vous devriez certainement utiliser' new [] 'et' delete [] 'au lieu de' malloc' et 'free'. Cependant, si les pointeurs ne sont pas obligatoires, vous devriez utiliser ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector) à la place. –

+1

Montrez-nous tout le code qui provoque cela et peut être exécuté (MCVE). N'utilisez pas non plus underscore-capital dans les noms (réservés). – lorro

+2

Je vous recommande également de prendre le temps de lire [Quelles sont les règles d'utilisation d'un trait de soulignement dans un identifiant C++?] (Http://stackoverflow.com/questions/228783/what-are-the-rules-about-using- an-underscore-in-ac-identifier) ​​Les symboles commençant par un trait de soulignement suivi d'une lettre majuscule (comme par exemple '_Stack') sont réservés. –

Répondre

2

sizeof(stack->capacity * sizeof(int)) dans votre appel à malloc est faux. Au lieu de la taille du tableau, il donne la taille du nombre utilisé pour représenter la taille du tableau. Vous voulez probablement stack->capacity * sizeof(int).

Un autre problème possible est qu'en C, vous ne devriez pas convertir la valeur de retour de malloc, car elle peut cacher d'autres erreurs et provoquer un plantage. Voir Do I cast the result of malloc? En C++, vous devrez le faire, en raison de la vérification de type plus stricte en C++, mais il peut toujours cacher des problèmes.

Ce sont les problèmes que je vois avec le code que vous avez montré. Cependant, rappelez-vous que les erreurs dans malloc et free ne sont pas nécessairement causées par la ligne réelle où elles sont détectées. Si une partie de votre programme endommage les structures de données internes du système malloc, par exemple par un dépassement de tampon, le problème peut se manifester par un appel beaucoup plus tard à malloc ou free, dans une partie complètement différente du programme.

+0

@Bob__: Ah, merci. J'ai manqué ça. –

3

Modifier ceci:

stack->arr = (int*) malloc(sizeof(stack->capacity * sizeof(int))); 

à ceci:

stack->arr = (int*) malloc(stack->capacity * sizeof(int)); 

puisque vous voulez la taille du tableau à être égal à stack->capacity * sizeof(int), et non égale à la taille de cette expression.

Votre programme doit avoir invoqué un comportement indéterminé quelque part dans le code non affiché dans la question (en raison de la mauvaise taille de la malloc), c'est pourquoi il se bloque plus tard.


PS: Puisque vous utilisez C++, envisagez d'utiliser new à la place (et delete, au lieu de free()).