7
votes

Comment libérer () un MALLOC () D structuré correctement?

J'ai une structure malloc () d, et après les utiliser, je veux libérer () cela, mais mon programme gèle ici. Quelqu'un peut-il me dire, ce que je fais mal?

Voici mon code: P>

struct data  
{  
char *filename;  
char *size;  
};   
 //primarypcs is a long type variable
struct data *primary = (struct data *)malloc( primarypcs * sizeof( struct data ) );  
memset( primary, 0, sizeof(struct data *) * primarypcs );  
...
...
...
for ( i = 0; i < primarypcs; i++ )  
{
   free( primary[i].filename );  //<----my program freezes here
   free( primary[i].size );      //<----or here
}
free( primary );  


6 commentaires

Je ne vois pas que vous affectation de mémoire pour nom de fichier et taille .


Oui, vous trouverez un bogue dans votre code: Dans le MALLOC, vous utilisez Tailleof (Struct Data) qui semble correct, mais dans Memset, vous utilisez Tailleof (Struct Data *) qui est la moitié de la taille. Cela signifie que vous n'avez que la moitié de la mémoire éteinte et que le dernier 1/2 de la mémoire fera la barre lorsque vous essayez de le libérer. La réponse devrait être libre (primaire); Et rien de plus


S'il s'agit de C ++, vous devez utiliser de nouvelles et supprimez.


@Xorlev: J'ai déjà mentionné que dans ma réponse. Voir ma réponse ci-dessous.


Vous devez sélectionner C ++ ou C comme langue. Votre échantillon est en C, pas C ++.


Sur la base de votre deuxième édition, vous voulez Taille d'un type intégré, tel que Taille_t , pas char * . Voir ma réponse pour plus de détails.


8 Réponses :


3
votes

Comment sont les cordes de la structure allouées? S'ils sont statiquement attribués aux constantes, ne leur libérez pas de cette façon, et tout ce qui est nécessaire, c'est gratuit (primaire); libérant quelque chose qui n'était pas maladraté donnera une saisie de coeur .

Si les pointeurs de cordes sont définis par Malloc () ou CalloC (), c'est la bonne manière.


0 commentaires

7
votes

Vous ne présentez pas tout le code, où beaucoup de choses peuvent se tromper, mais une erreur est déjà évidente. La ligne xxx

ne fait pas ce que vous pensez que cela fait. Il ne s'agit pas de zéro de la matrice entière due à une erreur de type dans Tailleof . C'était probablement censé être xxx

note no. code> * sous taille de . En raison de cette erreur, la plupart des pointeurs de votre matrice contiennent des ordures comme leurs valeurs initiales. Si vous ne les définissez pas sur quelque chose de significatif dans le code omis, vos appels vers GRATUIT recevront des arguments de déchets et échoueront.

en général, afin de réduire les chances de telles erreurs Il est préférable d'éviter de mentionner les noms de type dans votre programme, sauf dans les déclarations. Étant donné que votre question est étiquetée C ++ (même si elle ressemble sûrement à c), il n'est pas possible de se débarrasser de types de jeux de type sur malloc , mais sinon je dirais que ce qui suit a l'air mieux xxx

et, comme note latérale, si votre code était destiné à être C ++, vous pouvez obtenir le même résultat de manière beaucoup plus élégante, compacte et portable XXX

Bien sûr, dans ce cas, vous devrez distribuer la mémoire à l'aide de la fonctionnalité C ++ appropriée au lieu de gratuit .


1 commentaires

Salut! Merci de vous pour votre aide. C'était l'une de mes erreurs, BTUT après avoir corrigé mon code par votre réponse, mon programme toujours gelé. Plus tard, j'ai réalisé que j'y ai mal ayé une de mes variables, et je ne faisais que la mémoire pour 5 articles, mais j'ai inséré plus de 5 articles dans la structure. Merci encore!



0
votes

Remplacement de la boucle pour la boucle en bas de votre code avec gratuit (primaire); devrait fonctionner.


0 commentaires

0
votes

En effet, vous n'avez pas explicitement attribué la mémoire pour nom de fichier et de taille . Tellement essayant de faire gratuit (primaire [i] .filename); ou gratuit (primaire [i] .Size); invoquerait comportement indéfini .

juste gratuit (primaire) est suffisant.

edit :

Cette question a été étiquetée C ++. Donc, la manière C ++ est d'utiliser nouveau au lieu de malloc pour les types définis par l'utilisateur.

pour les différences entre nouveau et < Code> MALLOC Jetez un coup d'œil à Ceci .

dans c ++ , il vous suffit d'écrire xxx


1 commentaires

Le code de l'échantillon peut être considéré comme ok, présumant individuellement Malloc le nom de fichier. Avoir une «taille» de Malloc'ed semble suspicieusement buggy, une taille_t conviendrait probablement mieux (à moins que ce soit vraiment une chaîne de charme)



0
votes

Ceci corrige votre problème dans MEMSET, qui a provoqué toutes sortes de problèmes pour vous.

memset( primary, 0, sizeof(struct data) * primarypcs );  


0 commentaires

2
votes

Si vous faites cela en C ++, vous ne devez pas utiliser quelque chose comme: xxx pré>

à la place, vous devez utiliser quelque chose comme: P>

struct data {
    std::string filename;
    std::string size;
};

std::vector<data> primary(primarypcs);


0 commentaires

1
votes

Comme d'autres l'ont dit, il y a deux choses évidemment erronées dans l'extrait que vous avez montré:

  1. Vous n'allez pas allouer de la mémoire pour nom de fichier et Taille membres des Structs vient d'attribuer,
  2. Votre memset () appel utilise la mauvaise taille.

    Votre memset () L'appel pourrait être simplifié et corrigé par: xxx

    Il y a un autre problème subtil avec votre code: C Standard ne garantit pas que tous les bits-zéro sont la constante de pointeur NULL (c.-à-d. NULL), de sorte que MEMSET () n'est pas la bonne façon de définir un pointeur sur null . Une manière portable de faire ce que vous voulez faire est la suivante: xxx

    pour allouer la mémoire pour nom de fichier et taille , il dépend de ce que vous voulez. Disons que vous déterminez que nom de fichier nécessite n octets et Taille nécessite m . Ensuite, votre boucle change à quelque chose comme ceci: xxx

    Vous pouvez omettre la multiplication avec Tailleof * primaire [i] .filename et et et et et et taille de * primaire [i] .Size à partir de ce qui précède si vous souhaitez: c garantit que tailleOf (char) est 1. J'ai écrit ce qui précède et pour le cas lorsque Nom de fichier et Taille Modifier les types.

    Aussi, notez que si nom_file est une chaîne de longueur k k , alors vous avez besoin de (k + 1) octets pour celui-ci, en raison de la terminaison 0 (donc n == k + 1 ci-dessus).

    Si je devais supposer, vous voulez Taille pour stocker la longueur du nom de fichier correspondant ? Si tel est le cas, taille ne doit pas être un char * mais un taille_t . Mais puisque je ne sais pas comment vous envisagez d'utiliser nom de fichier et (code> , je ne suis pas sûr.

    Assurez-vous de vérifier la valeur de retour de malloc () . Il renvoie null pour échec. J'ai omis le chèque du code ci-dessus pour la simplicité.

    Votre message a été étiqueté C ++ aussi, donc si vous êtes prêt à utiliser C ++, une solution C ++ est également disponible.


2 commentaires

Salut! Comment dois-je attribuer correctement la mémoire pour le nom de fichier et la taille?


Salut! la taille est char * dans un but. Je reçois la taille du fichier dans une longue, mais plus tard, je dois l'utiliser comme un caractère, alors je le convertit de Int en caractères, puis la stocker dans la structure.



0
votes

Vous avez omis de déformer l'ensemble de la matrice entraînant un pointeur de mémoire à déchets libérés. Utilisez calloc au lieu de MALLOC / MEMSET pour éviter cette erreur:

for (i = 0; i < primarypcs; ++i) {
    primary[i].filename = malloc(...);
    primary[i].size = malloc(...);
}


0 commentaires