1
votes

Comment libérer la mémoire d'un pointeur char à l'intérieur d'un pointeur struct

Je suis capable d'attribuer des valeurs avec strdup et d'imprimer les valeurs avec ceci: (* test + index) -> email mais je ne sais pas comment libérer la mémoire allouée à la variable email. J'ai pensé à libérer test + index mais je suppose que cela provoquerait une fuite de mémoire, non? En tenant compte du fait que la structure a alloué de la mémoire et que chacun des pointeurs à l'intérieur a de la mémoire allouée avec strdup .

Le code est à peu près comme ceci:

struct random {
    char *email;
} Random;

void function(Random **struct) {
    char *temp = calloc(100, sizeof(char));
    *struct = calloc(5, sizeof(Random));
    for (int i = 0; i < 5; i++) {
        scanf("%s", temp);
        (*struct + i)->email = strdup(temp); //This works
    }
    free((*struct + 3)->email); //Gives segmentation fault
}

int main() {
    Random *struct;

    function(&struct)
}


5 commentaires

Avez-vous omis un code ici? Parce que scanf en temp non initialisé va être un comportement non défini. temp doit être malloc édité, ou transformé en un tableau, pas seulement un char * . De plus, vous utilisez ici * struct + i , ce qui n'a aucun sens, étant donné qu'il n'y a pas de variable i , ni de variable randomSize .


@ShadowRanger Oui, j'ai essayé de simplifier l'exemple autant que possible. J'ai oublié la partie malloc. temp est initialisé avec calloc.


pourquoi ajoutez-vous i ? vous allez devoir mettre suffisamment de code pour reproduire le problème


Vous allez devoir fournir un exemple réel minimal reproductible (assurez-vous qu'il compile, s'exécute et a la même erreur que votre code complet), nous ne pouvons pas simplement deviner quelles autres erreurs vous faites lorsque vous coupez le code si mal.


C11 Standard - 6.4.1 Mots clés , votre utilisation de struct en tant que nom de variable n'est pas autorisé.


3 Réponses :


1
votes

Si je ne me trompe pas, n'est-ce pas?

free(*(test+index)->email);
free(text+index);


2 commentaires

J'obtiens un défaut de segmentation lorsque j'essaye cela. Peut-être que la modification pourrait clarifier les choses? Je ne suis pas sûr.


Ce serait gratuit ((* (test + index)) -> email) , je pense. Ou, mieux, gratuit (test [index] -> email); et libre (texte [index]); `.



0
votes

veuillez lire / comprendre: priorité des opérateurs C

Ensuite, notez que l'opérateur de dé-référence * a une priorité inférieure à l'opérateur + ,

Par conséquent, le code publié doit être modifié pour utiliser quelque chose comme:

(*mystruct)+i = ...

etc. Sinon, le + sera exécuté avant le *


1 commentaires

unaire * évalue avant le binaire + , qui est généralement désigné comme ayant une priorité plus élevée , pas inférieure. * s + i équivaut à (* s) + i , les parenthèses ne changent rien.



1
votes

Le code publié ne compile pas:

  • vous ne pouvez pas utiliser struct comme nom d'une variable. struct est un mot-clé.
  • Random est une variable globale, pas un type.

Il est idiomatique et beaucoup plus simple en C de renvoyer le résultat au lieu de passer son adresse comme argument.

Suite à ces remarques, et en ajoutant des vérifications de base, le code devrait être simplifié comme :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct Random {
    char *email;
} Random;

Random *function(void) {
    char *temp = calloc(100, sizeof(char));
    if (temp == NULL)
        return NULL;
    Random *s = calloc(5, sizeof(Random));
    if (s != NULL) {
        for (int i = 0; i < 5; i++) {
            if (scanf("%99s", temp) != 1)
                *temp = '\0';
            (s + i)->email = strdup(temp); //This works
        }
        free((s + 3)->email); //Gives segmentation fault
    }
    free(temp);
    return s;
}

int main() {
    Random *s = function();
    // ...
}

Ce code, sémantiquement équivalent à votre fragment publié, n'a pas de comportement indéfini là où vous indiquez, votre code réel doit faire autre chose.

p>


0 commentaires