IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Allocation dynamique, malloc, free


Sujet :

C

  1. #1
    Membre confirmé Avatar de nl.smart
    Homme Profil pro
    ouvrier
    Inscrit en
    Avril 2019
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : ouvrier
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 155
    Points : 534
    Points
    534
    Par défaut Allocation dynamique, malloc, free
    Bonjour,

    Le code ci-dessous fonctionne mais il affiche un message d'erreur en fin d’exécution dans la console lorsque le nombre de personnes dépasse 2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    #include <stdio.h>  // ok linux
    #include <stdlib.h> //
    #include <time.h>   //
    #include <string.h>
     
    int main()
    {
        int nbre_personnes, i = 0;
     
        char *prenom_personnes[50];
     
        int *ptr_age_personnes = NULL;
     
        printf("\n Combien de personnes sont ici présentes ? ");
        scanf("%d", &nbre_personnes);
     
        if (nbre_personnes > 0)
        {
            *prenom_personnes = malloc(nbre_personnes * sizeof (int)); // il doit y avoir une erreur ici, le pointeur et int...
     
            ptr_age_personnes = malloc(nbre_personnes * sizeof (int));
     
            if (nbre_personnes == 0)
            {
                exit(0);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n Quel est le prénom de la personne %d ? ", i + 1);
                scanf("%s", prenom_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n Quel âge a %s ? ", prenom_personnes[i]);
                scanf("%d", &ptr_age_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n %s a %d an%c ", prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
            }
     
            free(ptr_age_personnes); // Un seul malloc est libéré, un messages d'erreur s'affiche dans l'ide si j'essaye de libérer le second.
     
            printf("\n");
        }
     
        return 0;
    }
    message d'erreur de la console ci-dessous :

    Nom : Allocation dynamique, malloc, free....png
Affichages : 2236
Taille : 12,2 Ko

    Merci pour vos lumières, les corrections et le cour que vous me donnerez :-)

    Nicolas.

  2. #2
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Bonsoir.

    prenom_personnes est déclaré comme un tableau de pointeur.

    Ligne 19 tu perds le pointeur sur le premier élément de ce tableau en le remplaçant par une simple allocation.
    Il faut écrire prenom_personnes [x] = malloc (); où x est un index sur les éléments du tableau.

    Autre remarque. La condition ligne 23 ne sert à rien puisqu’elle est incluse dans la condition qui vérifie que nbre_personnes>0.

  3. #3
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut
    Salut, tu utilises des pointeurs et tu fais des allocations dynamiques, donc je pense que tu en es assez loin pour utiliser des structures qui serait plus adapter pour ton code.
    Ah oui, si tu alloues 50 fois un prenom, alors 50 fois faudra faire un free(). Il y a mieux mais bon je te laisse chercher.
    Et en temps normal, on vérifie les retours de malloc, au cas ou sa renvoie NULL et que tu te retrouves bien embeter


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
     
    #include <stdio.h>  // ok linux
    #include <stdlib.h> //
    #include <time.h>   //
    #include <string.h>
     
    int main()
    {
        int nbre_personnes, i = 0;
     
        char *prenom_personnes[50]; // Tableau de 50 pointeurs de type char * ( potentiellement 50 prenoms ) 
     
        int *ptr_age_personnes = NULL;
     
        printf("\n Combien de personnes sont ici présentes ? ");
        scanf("%d", &nbre_personnes);
     
        if (nbre_personnes > 0)
        {
            // Ici il y a un probleme, tu ne connais pas encore le nombre de caractere pour "prenom_personnes" pour allouer de la memoire
            // De plus ton allocation est fausse ce serait plutot pour le premier prenom : "prenom_personnes[0]" Tu as 50 pointeurs, donc ici ce sera de 0 à 49 pour l'indice
            // Pour recuperer les prenoms tu devrais utiliser fgets, car scanf faut le maitriser. Prototypes : char * fgets( char * string, int maxLength, FILE * stream );   Ici à la place de stream tu indiques stdin pour ton clavier
            // Tes allocations doivent etre faites au moment ou tu recuperes les prenoms
            // Tu peux aussi utiliser la fonction strnlen pour connaitre le nombre de caractere entrer par l'utilisateur en fixant une limite pour la taille devant etre allouer et prevoir + 1 pour le caractere de fin de chaine
            *prenom_personnes = malloc(nbre_personnes * sizeof (int)); // Ici tu alloues le nombre de personnes multiplier par la taille d'un int, sa ne va pas
     
            ptr_age_personnes = malloc(nbre_personnes * sizeof (int));
     
            if (nbre_personnes == 0)
            {
                exit(0);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n Quel est le prénom de la personne %d ? ", i + 1);
                scanf("%s", prenom_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n Quel âge a %s ? ", prenom_personnes[i]);
                scanf("%d", &ptr_age_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n %s a %d an%c ", prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
            }
     
            free(ptr_age_personnes); // Un seul malloc est libéré, un messages d'erreur s'affiche dans l'ide si j'essaye de libérer le second.
     
            printf("\n");
        }
     
        return 0;
    }

  4. #4
    Membre confirmé Avatar de nl.smart
    Homme Profil pro
    ouvrier
    Inscrit en
    Avril 2019
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : ouvrier
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 155
    Points : 534
    Points
    534
    Par défaut
    Bonjour,

    Merci pour vos réponses, il y a matière à travailler.

    Les structures seront l'étape suivante pour cet exemple d'allocation dynamique.

    Je me penche sur vos explications et je reviendrai plus tard avec un meilleur code.

    J'ai retravaillé le code ce matin, le voilà, il en reste à corriger...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    #include <stdio.h>  // ok linux
    #include <stdlib.h> //
    #include <time.h>   //
    #include <string.h>
     
    int main()
    {
        int nbre_personnes, i = 0;
     
        char *prenom_personnes;
     
        int *ptr_age_personnes;
     
        printf("\n Combien de personnes sont ici présentes ? ");
        scanf("%d", &nbre_personnes);
     
            prenom_personnes = (char *) malloc(50 * sizeof (char));
     
            ptr_age_personnes = (int *) malloc(4 * sizeof(int));
     
            if (prenom_personnes == 0 || ptr_age_personnes == 0)
            {
                exit(0);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n Quel est le prénom de la personne %d ? ", i + 1);
                scanf("%s", &prenom_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++) // il y a un problème avec cette boucle lors de l'exécution du code, je verrai ça demain
            {
                printf("\n Quel âge a %s ? ", &prenom_personnes[i]);
                scanf("%d", &ptr_age_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n %s a %d an%c ", &prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
            }
     
            free(prenom_personnes);
            free(ptr_age_personnes);
     
            printf("\n");
     
        return 0;
    }
    Nicolas.

  5. #5
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut
    Inutile de caster le retour de malloc


    EDIT : Je te montre juste un bout de codes fonctionnel, mais qu'on ecrit pas de cette façon, pourquoi ?
    1 : Aucune vérification du retour de malloc()
    2 : fonction de saisie devant être personnaliser, ton programme est à la merci de l'utilisateur
    3 : Si pendant une allocation il y a une erreur, alors boom, fuite mémoire

    Je te laisse rendre ton code plus robuste en étudiant les corrections faites, mais loin d’être parfaite car j'ai garder toute l'organisation de ton programme, et j'ai pas vérifier mes allocations et gérer les cas plus hard

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    #define MAX_PRENOM 40
     
    int main(void)
    {
        int nbre_personnes;
        int nbr;
        int i = 0;
        char buf[MAX_PRENOM];
        char **prenom_personnes; // Ici création d'un pointeur de type char * qui va pointer sur un pointeur ou des pointeurs de type char *
        int *ptr_age_personnes;
     
        printf("\n Combien de personnes sont ici présentes ? ");
        scanf("%d", &nbre_personnes);
        if (nbre_personnes <= 0)
        {
          printf("\n***Le programme va se terminer, erreur de saisie***\n");
          return EXIT_FAILURE;
        }
     
        prenom_personnes = malloc(nbre_personnes * sizeof (char *)); // Création du tableau de pointeurs de type char *, avec pour un pointeur char * == une chaine à allouer.
        ptr_age_personnes = malloc(nbre_personnes * sizeof(int));
     
        for (i = 0 ; i < nbre_personnes ; i++)
        {
          printf("\n Quel est le prénom de la personne %d ? ", i + 1);
          scanf("%s", buf);
          nbr = strlen(buf); // strlen() retourne le nombre de caractères contenu dans buf sans le caractère de fin de chaine
          printf("Nombre de caracteres du prenom : %d\n", nbr);
          prenom_personnes[i] = malloc((nbr + 1) * sizeof(char));
          memmove(prenom_personnes[i], buf, nbr + 1); // Avant de comprendre ce que fait memmove(), tu peux à la place utiliser strncpy() avec les mêmes arguments
     
          printf("\n Quel âge a %s ? ", prenom_personnes[i]);
          scanf("%d", &ptr_age_personnes[i]);
        }
     
        printf("\n");
        for (i = 0 ; i < nbre_personnes ; i++)
        {
          printf("%s a %d an%c\n", prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
        }
        printf("\n");
     
        for (i = 0 ; i < nbre_personnes ; i++)
        {
          free(prenom_personnes[i]);
        }
     
        free(prenom_personnes);
        free(ptr_age_personnes);
     
     
        return EXIT_SUCCESS;
    }

  6. #6
    Membre confirmé Avatar de nl.smart
    Homme Profil pro
    ouvrier
    Inscrit en
    Avril 2019
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : ouvrier
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 155
    Points : 534
    Points
    534
    Par défaut
    Bonjour,

    Comme je le craignais en créant ce poste des notions non vues (mais que je devine pointer à l'horizon) ont été abordées :

    _ buffer
    _ fonction memmove() et strncpy()
    _ saisie de texte sécurisée, liée au buffer (j'ai hâte d'aborder ce point, par ce qu'à l’heure actuelle bonjour les fuites mémoires et autres bugs potentiels dans mon code avec scanf )
    _ pointeur d'adresse sur l'adresse d'une variable (jusqu'à présent un pointeur se limitait pour moi à être une variable qui contenait l'adresse d'une autre variable)
    _ ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        /* écrit par gerald3d, citation que j'avais alors copiée et conservée
        char : variable de type entier pouvant aller de -127 à +128
        char* : pointeur d'adresse sur une variable de type char
        char ** : pointeur d'adresse sur l'adresse d'une variable de type char
        */
    ci-dessous le code réalisé ce matin fonctionnant sous linux puis testé sous windows.

    La vérification des malloc est faite au début du programme tout comme leur libération en fin de programme, manque la saisie de texte sécurisée pour laquelle je reviendrai plus tard car non abordée dans le cour que je suis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    #include <stdio.h>  // ok linux et windows
    #include <stdlib.h> //
    #include <time.h>   //
    #include <string.h>
     
    int main()
    {
        int nbre_personnes, i = 0;
     
        char **ptr_prenom_personnes = NULL; // création d'un pointeur d'adresse sur l'adresse d'une variable de type char
     
        int *ptr_age_personnes = NULL;
     
        printf("\n Combien de personnes sont ici présentes ? ");
        scanf("%d", &nbre_personnes);
     
            //ptr_prenom_personnes = malloc(sizeof(char*) * 50); // allocation des pointeurs sur les variables de type char
            ptr_prenom_personnes = malloc(sizeof(*ptr_prenom_personnes) * 50); // autre écriture de précédemment
     
            //ptr_age_personnes = malloc(sizeof(int*) *4);
            ptr_age_personnes = malloc(sizeof(*ptr_age_personnes) * 4);
     
     
            if (ptr_prenom_personnes == 0 || ptr_age_personnes == 0) // vérification de l'allocation de mémoire
            {
                return EXIT_FAILURE;
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                //ptr_prenom_personnes[i] = malloc(sizeof (char*) * 50); // création des tableaux qui contiendront les noms
                ptr_prenom_personnes[i] = malloc(sizeof(*ptr_prenom_personnes[i]) * 50);  // autre écriture de précédemment
     
                printf("\n Quel est le prénom de la personne %i ? ", i + 1);
                scanf("%s", ptr_prenom_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n Quel âge a %s ? ", ptr_prenom_personnes[i]);
                scanf("%d", &ptr_age_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n %s a %d an%c ", ptr_prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
            }
            // libération de la mémoire allouée ci-après
            for (i = 0; i < nbre_personnes; i++)
            {
                 free(ptr_prenom_personnes[i]); // libération de tous les prénoms renseignés
            }
     
            free(ptr_prenom_personnes);
            free(ptr_age_personnes);
     
            printf("\n");
     
        return EXIT_SUCCESS;
    }
    https://stackoverflow.com/questions/...or-0-from-main

    Je passerai le poste en résolue lorsque j'aurai réalisé l'allocation dynamique avec une structure, je tenterai ça demain matin...

    Encore merci pour vos lumières :-)

    Nicolas.

  7. #7
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut
    Euh comment dire ? J'ai du t'induire en erreur.

    Je ne peux commenté comme il faut je suis au boulot et sur smartphone sa va pas, mais ton nouveau code


    Pourquoi obliger à 50 entrées, si tu as moins alors tu alloues pour rien, et si tu as besoin de plus tu ne pourras pas !!!
    De plus, tu accordes 50 prénoms mais seulement 4 entrées pour age. (C'est tout le problème des chiffres magiques)

    Tu fixes maladroitement le nombre de personnes à 50, alors ne demande pas combien de personnes il faut entrer sa sert à rien.

    Le buf c'etait juste pour limiter arbitrairement la taille d'une chaine.

    Ici dans ce nouveau code, un programme comme valgrind t'aurai flingué. EDIT : Je retire ce commentaire car j'ai lu ça à la va vite sur petit écran

    Non malheureusement tu ne verifies aucun retour des malloc().

    Sa prendrai la forme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    int *alloc = malloc(sizeof(int));
    if(alloc == NULL)
    {
    // Ici tu indiquerais la marche à suivre si la zone de memoire demandé  ne t'etais pas accordé
    }
    Dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
     if (ptr_prenom_personnes == 0 || ptr_age_personnes == 0) // Admettons que ptr_prenom_personnes soit allouer, et non ptr_age_personnes, alors fuites mémoires
            {
                return EXIT_FAILURE;
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                ptr_prenom_personnes[i] = malloc(sizeof(*ptr_prenom_personnes[i]) * 50);  // Ou verifies-tu le retour malloc pour chaque allocations ici ?
     
                printf("\n Quel est le prénom de la personne %i ? ", i + 1);
                scanf("%s", ptr_prenom_personnes[i]);
            }

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par nl.smart Voir le message
    ci-dessous le code réalisé ce matin fonctionnant sous linux puis testé sous windows.
    et pourtant erroné...

    Citation Envoyé par nl.smart Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include <stdio.h>  // ok linux et windows
    #include <stdlib.h> //
    #include <time.h>   //
    #include <string.h>
    
    int main()
    {
        int nbre_personnes, i = 0;
    
        char **ptr_prenom_personnes = NULL; // création d'un pointeur d'adresse sur l'adresse d'une variable de type char
    
        int *ptr_age_personnes = NULL;
    
        printf("\n Combien de personnes sont ici présentes ? ");
        scanf("%d", &nbre_personnes);
    
            //ptr_prenom_personnes = malloc(sizeof(char*) * 50); // allocation des pointeurs sur les variables de type char
            ptr_prenom_personnes = malloc(sizeof(*ptr_prenom_personnes) * 50); // autre écriture de précédemment
    
            //ptr_age_personnes = malloc(sizeof(int*) *4);         sizeof(int*) ? t'es sûr ???
            ptr_age_personnes = malloc(sizeof(*ptr_age_personnes) * 4);
    
    
            if (ptr_prenom_personnes == 0 || ptr_age_personnes == 0) // vérification de l'allocation de mémoire
            {
                return EXIT_FAILURE;
                // Pas bon - Si une des allocations a réussi et pas l'autre alors tu ne la libères pas - Et conventionnellement on teste un pointeur avec NULL, pas avec 0
            }
    
            for (i = 0; i < nbre_personnes ; i++)
            {
                //ptr_prenom_personnes[i] = malloc(sizeof (char*) * 50); // création des tableaux qui contiendront les noms => sizeof(char*) ? t'es sûr ???
                ptr_prenom_personnes[i] = malloc(sizeof(*ptr_prenom_personnes[i]) * 50);  // autre écriture de précédemment
    
                printf("\n Quel est le prénom de la personne %i ? ", i + 1);
                scanf("%s", ptr_prenom_personnes[i]);
            }
    
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n Quel âge a %s ? ", ptr_prenom_personnes[i]);
                scanf("%d", &ptr_age_personnes[i]);
            }
    
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n %s a %d an%c ", ptr_prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
            }
            // libération de la mémoire allouée ci-après
            for (i = 0; i < nbre_personnes; i++)
            {
                 free(ptr_prenom_personnes[i]); // libération de tous les prénoms renseignés
            }
    
            free(ptr_prenom_personnes);
            free(ptr_age_personnes);
    
            printf("\n");
    
        return EXIT_SUCCESS;
    }
    Mes remarques en rouge dans ton code. Pas beaucoup d'erreurs mais tellement destructrices...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre confirmé Avatar de nl.smart
    Homme Profil pro
    ouvrier
    Inscrit en
    Avril 2019
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : ouvrier
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 155
    Points : 534
    Points
    534
    Par défaut
    Bonjour,

    ça avance :-)

    Est-ce que vérifier les retours de malloc équivaut à vérifier l'allocation de mémoire ?

    Le morceau de code ci-dessous a pourtant fonctionné... à moins que la remarque ai été faite pour remarquer que le code ne disposait que de 4 entrées pour l'âge... ce qui a été corrigé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ptr_age_personnes = malloc(sizeof(int*) *4);
    Ci-après le code complet en tenant compte de vos remarques :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #include <stdio.h>  // ok linux et windows
    #include <stdlib.h> //
    #include <time.h>   //
    #include <string.h>
     
    int main()
    {
        int nbre_personnes, i = 0;
     
        char **ptr_prenom_personnes = NULL;
     
        int *ptr_age_personnes = NULL;
     
        printf("\n Combien de personnes sont ici présentes ? ");
        scanf("%d", &nbre_personnes);
     
            ptr_prenom_personnes = malloc(nbre_personnes * sizeof(char*));
     
            ptr_age_personnes = malloc(nbre_personnes * sizeof(int));
     
            if (ptr_prenom_personnes == NULL && ptr_age_personnes == NULL) // est-ce correct ?
            {
                return EXIT_FAILURE;
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                ptr_prenom_personnes[i] = malloc(sizeof(*ptr_prenom_personnes[i]));
     
                if (ptr_prenom_personnes[i] == NULL) // vérification de l'allocation de mémoire, est-ce correct ?
                {
                    return EXIT_FAILURE;
                }
     
                printf("\n Quel est le prénom de la personne %i ? ", i + 1);
                scanf("%s", ptr_prenom_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n Quel âge a %s ? ", ptr_prenom_personnes[i]);
                scanf("%d", &ptr_age_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n %s a %d an%c ", ptr_prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
            }
            // libération de la mémoire allouée ci-après
            for (i = 0; i < nbre_personnes; i++)
            {
                 free(ptr_prenom_personnes[i]); // libération de tous les prénoms renseignés
            }
     
            free(ptr_prenom_personnes);
            free(ptr_age_personnes);
     
            printf("\n");
     
        return EXIT_SUCCESS;
    }
    Nicolas.

  10. #10
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut
    Les commentaires en rouge sont une bonne idée je pense.

    EDIT : Je ne sais pas si tu avais changé quelque chose entre temps au code ou si j'ai biglé, mais en l’état ne tient pas compte de mes remarques lignes 29. Par contre il faut fixé un nombre de caracteres à allouer pour ta chaine

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    #include <stdio.h>  // ok linux et windows
    #include <stdlib.h> //
    #include <time.h>   //
    #include <string.h>
     
    int main()
    {
        int nbre_personnes, i = 0;
     
        char **ptr_prenom_personnes = NULL;
     
        int *ptr_age_personnes = NULL;
     
        printf("\n Combien de personnes sont ici présentes ? ");
        scanf("%d", &nbre_personnes);
     
            ptr_prenom_personnes = malloc(nbre_personnes * sizeof(char*));
     
            ptr_age_personnes = malloc(nbre_personnes * sizeof(int));
     
            if (ptr_prenom_personnes == NULL && ptr_age_personnes == NULL) // Si ptr_prenom_personnes est ok mais que ptr_age_personnes est NULL alors fuites mémoires puisque que tu quittes sans faire un free de ptr_prenom_personnes.
    Je rajoute après un nouveau EDIT, que ton && (et puis) aussi ne va pas, pour ce que tu voulais faire, sa aurait du être || (ou bien)
            {
                return EXIT_FAILURE;
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                ptr_prenom_personnes[i] = malloc(sizeof(*ptr_prenom_personnes[i])); // Ici faut que tu saches que le nombre de caractères que tu autorises est max 7 + 1 de fin de chaines. Pourquoi ? 
                Parce que tu fais un sizeof sur un pointeur est que celui-ci fera sur un ordi 64 bits 8 octets, 
                et si tu es sur du 32 bits alors tu auras droit à 4 octets pour le pointeur. Mais si on dépasse ce nombre de caractères, BOOM écriture dans une 
                zone mémoire pouvant être alloués à un autre programme. SEGMENTATION FAULT 
     
                if (ptr_prenom_personnes[i] == NULL) // vérification de l'allocation de mémoire, est-ce correct ? Oui, mais non en faites, pourquoi ? fuites mémoires, on ne quitte pas un programmes sans libérer les zones précédemment allouées. C'est juste une question d'organisation du code qui fait que tu en es là, mais sa va beaucoup mieux qu'avant
                {
                    return EXIT_FAILURE;
                }
     
                printf("\n Quel est le prénom de la personne %i ? ", i + 1);
                scanf("%s", ptr_prenom_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n Quel âge a %s ? ", ptr_prenom_personnes[i]);
                scanf("%d", &ptr_age_personnes[i]);
            }
     
            for (i = 0; i < nbre_personnes ; i++)
            {
                printf("\n %s a %d an%c ", ptr_prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
            }
            // libération de la mémoire allouée ci-après
            for (i = 0; i < nbre_personnes; i++)
            {
                 free(ptr_prenom_personnes[i]); // libération de tous les prénoms renseignés
            }
     
            free(ptr_prenom_personnes);
            free(ptr_age_personnes);
     
            printf("\n");
     
        return EXIT_SUCCESS;
    }

  11. #11
    Expert confirmé
    Avatar de gerald3d
    Homme Profil pro
    Conducteur de train
    Inscrit en
    Février 2008
    Messages
    2 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Conducteur de train
    Secteur : Transports

    Informations forums :
    Inscription : Février 2008
    Messages : 2 291
    Points : 4 941
    Points
    4 941
    Billets dans le blog
    5
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (ptr_prenom_personnes == NULL && ptr_age_personnes == NULL) // est-ce correct ?
            {
                return EXIT_FAILURE;
            }
    Malheureusement non. Ou du moins c'est une moitié de non .
    Imaginons que ptr_prenom_personnes soit bon et pas ptr_age_personnes, que se passe-t-il ?

  12. #12
    Membre confirmé Avatar de nl.smart
    Homme Profil pro
    ouvrier
    Inscrit en
    Avril 2019
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : ouvrier
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 155
    Points : 534
    Points
    534
    Par défaut
    Bonjour,

    Est-ce correct ainsi ?

    || a été déconseillé par Sve@r

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ptr_prenom_personnes = malloc(nbre_personnes * sizeof(char*)); 
            if (ptr_prenom_personnes == NULL)
            {
                return EXIT_FAILURE;
            }
     
    ptr_age_personnes = malloc(nbre_personnes * sizeof(int));
    if (ptr_age_personnes == NULL)
            {
                return EXIT_FAILURE;
            }
    Le dépassement de caractères peut-il être résolu avec fgets ?

    Nicolas.

  13. #13
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut
    J'ai fais une légère modification pour que tu vois ou je voulais en venir.

    || a été déconseillé par Sve@r
    Non Sve@r à aucun moment ne te parle des opérateurs logiques && ou ||

    Relis à tête reposé les explications de tout le monde plus haut.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    ptr_prenom_personnes = malloc(nbre_personnes * sizeof(char*)); 
            if (ptr_prenom_personnes == NULL)
            {
                return EXIT_FAILURE;
            }
     
    ptr_age_personnes = malloc(nbre_personnes * sizeof(int));
    if (ptr_age_personnes == NULL)
            {
                free(ptr_prenom_personnes); // Je libère le bloc mémoire allouée plus haut et je quitte le programme sans fuite mémoire
                return EXIT_FAILURE;
            }

  14. #14
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par nl.smart Voir le message
    || a été déconseillé par Sve@r
    Moi j'ai déconseillé le connecteur "or" ??? Certes il est vrai qu'on peut toujours remplacer a or b par not(not(a) and not(b)) mais bon, je ne vois pas pourquoi j'aurais déconseillé cet élément aussi fondamental du langage et de la logique booléenne
    Et puis pour deux opérandes ça va encore mais s'il faut le faire pour un truc du style a or b and (c or d) ça va vite devenir chaud

    Tu m'as mal compris: ce que je déconseille c'est le test global de toutes les allocations d'un coup parce que tu ne sauras pas quoi faire si seulement l'une d'elles échoue (ou si l'autre d'elles réussit c'est comme tu le sens). Et c'est donc bien entendu tout aussi valable pour ton second essai avec "&&". Ce n'est pas le "and" qui est condamnable, c'est le trou que ce test laisse passer comme situation non gérée.

    Pour le reste voir le post de Proteiforme. Chaque demande de ressource (allocation, ouverture de fichier, etc) doit être testée individuellement.

    Ensuite il y a le coup des allocations en boucle. Tu en demandes 50, mais quoi faire si la 45° échoue ?

    Je peux te proposer la solution type suivante
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    char **tab;
    size_t i;
    tab=calloc(n, sizeof(*tab));                 // calloc met tout à 0
    if (tab == NULL)
    	return ...;
     
    for (i=0; i < n; i++) {
    	tab[i]=malloc(... * sizeof(*tab[i]));
    	if (tab[i] == NULL) goto 1945;		// oui oui, un vrai "goto", le truc maudit des progs (mais seulement des progs qui ne savent pas s'en servir avec concision et clarté et qui, peut-être, sont aussi un peu pusillanimes et superstitieux...)
    }
    ... (traitement)...
     
    1945:			// La libération !!!
    for (i=0; i < n; i++) free(tab[i]);		// soit tab[i] est rempli d'une adresse allouée, soit il est à 0 => dans tous les cas free() l'accepte
    free(tab);



    Citation Envoyé par nl.smart Voir le message
    Le dépassement de caractères peut-il être résolu avec fgets ?
    Tout à fait. fgets(zone, n, buffer) s'arrête à n-1 caractères récupérés du buffer pour pouvoir rajouter le '\0'. Un petit écueil cependant, il récupère aussi (s'il a la place) le '\n' symbolisant le <return> tapé par l'utilisateur.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Membre confirmé Avatar de nl.smart
    Homme Profil pro
    ouvrier
    Inscrit en
    Avril 2019
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : ouvrier
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 155
    Points : 534
    Points
    534
    Par défaut
    Bonsoir,

    ci-dessous le code après lecture et application de vos remarques, merci.

    Manque les fgets, ça sera pour bientôt dans le cour que je suis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    #include <stdio.h>  // ok windows 32
    #include <stdlib.h> //
    #include <time.h>   //
    #include <string.h>
    
    int main()
    {
        int nbre_personnes;
        size_t i; // La valeur d'une opération sizeof est de type size_t
    
        char **ptr_prenom_personnes = NULL;
    
        int *ptr_age_personnes = NULL;
    
        printf("\n Combien de personnes sont ici présentes ? ");
        scanf("%d", &nbre_personnes);
    
        ptr_prenom_personnes = calloc(nbre_personnes, sizeof(*ptr_prenom_personnes));  // calloc met tous les octets du bloc à la valeur 0, malloc ne modifie pas la zone de mémoire
        if (ptr_prenom_personnes == NULL)
        {
            return EXIT_FAILURE;
        }
    
        ptr_age_personnes = malloc(nbre_personnes * sizeof(int));
        if (ptr_age_personnes == NULL)
        {
            free(ptr_prenom_personnes); // le dernier malloc contiendra-t-il le free de tous les précédents malloc ?
          //free(ceci);
          //free(cela);
            return EXIT_FAILURE;
        }
    
        for (i = 0; i < nbre_personnes ; i++)
        {
            ptr_prenom_personnes[i] = malloc(sizeof(*ptr_prenom_personnes[i]));
    
            if (ptr_prenom_personnes[i] == NULL)
            {
                goto lol; // goto envoie à la ligne 56, goto hell est-il placé correctement ?
            }
    
            printf("\n Quel est le prénom de la personne %i ? ", i + 1);
            scanf("%s", ptr_prenom_personnes[i]);
        }
    
         for (i = 0; i < nbre_personnes ; i++)
         {
            printf("\n Quel âge a %s ? ", ptr_prenom_personnes[i]);
            scanf("%d", &ptr_age_personnes[i]);
         }
    
         for (i = 0; i < nbre_personnes ; i++)
         {
            printf("\n %s a %d an%c ", ptr_prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
         }
         // libération de la mémoire allouée ci-après
    
         lol: // goto reçu de la ligne 37
    
         for (i = 0; i < nbre_personnes; i++)
         {
            free(ptr_prenom_personnes[i]); // libération de tous les prénoms renseignés
         }
    
         free(ptr_prenom_personnes);
         free(ptr_age_personnes);
    
         printf("\n");
    
        return EXIT_SUCCESS;
    }

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Ton code c'est plus que pas terrible

    Code non testé, non compilé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
     
     
    typedef struct s_one_person {
        char* first_name;
        size_t age;
    } t_one_person;
     
     
    void t_one_person_init(t_one_person* person) {
    /*  if (person != NULL) { */
            person->age = 0;
            person->first_name = NULL;
    /*  } */
    }
     
     
    void t_one_person_delete(t_one_person* person) {
        if (person != NULL) {
            if (person->first_name != NULL) {
                free(person->first_name);
            }
     
            t_one_person_init(person);
        }
    }
     
     
    unsigned char t_one_person_set_firstname(t_one_person* person, char* first_name) {
        unsigned char ret;
     
        if ((person != NULL) && (first_name != NULL)) {
            size_t len = strlen(first_name);
     
            if (len > 0) {
                person->first_name = malloc((len + 1) /** sizeof(char*)*/);
     
                if (person->first_name != NULL) {
                    strcpy(person->first_name, first_name);
    /*              person->first_name[len] = '\0'; */
     
                    ret = 1;
                } else {
                    ret = 0;
                }
            } else {
                ret = 0;
            }
        } else {
            ret = 0;
        }
     
        return ret;
    }
     
     
    int main(int argc, char** argv)
    {
        t_one_person* array_persons;
        char tmp_first_name[128];
        int nb_persons;
        size_t count, age;
        unsigned char is_okay;
     
        printf("\n Combien de personnes sont ici présentes ?");
        scanf("%d", &nb_persons);
     
        if (nb_persons <= 0) { return EXIT_FAILURE; }
     
        array_persons = malloc(nb_persons, sizeof(t_one_person));
     
        if (array_persons == NULL) { return EXIT_FAILURE; }
     
        for(count=0; count < nb_persons; ++count) {
            t_one_person_init( array_persons[count] );
        }
     
    /*  memset(tmp_first_name, '\0', 128); */
     
        for(is_okay=1, count=0; (is_okay && (count < nb_persons)); ++count) {
            printf("\n Quel est le prénom de la personne %i ? (max. 127 caractères)", (count + 1));
            scanf("%127s", tmp_first_name);
     
            if (!t_one_person_set_firstname(array_persons[count], tmp_first_name)) {
                is_okay = 0;
            }
        }
     
        if (is_okay) {
            for(count=0; count < nb_persons; ++count) {
                printf("\n Quel âge a %s ?", array_persons[count].first_name);
                scanf("%u", &age);
     
                array_persons[count].age = age;
            }
     
            for(count=0; count < nb_persons; ++count) {
                age = array_persons[count].age;
     
                printf("\n %s a %u %s", array_persons[count].first_name, age, ((age > 1)? 'ans': 'an'));
            }
        }
     
        for(count=0; count < nb_persons; ++count) {
            t_one_person_delete( array_persons[count] );
        }
     
        free(array_persons);
    /*  array_persons = NULL; */
     
        printf("\n");
     
        return (is_okay? EXIT_SUCCESS: EXIT_FAILURE);
    }

  17. #17
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par foetus Voir le message
    Ton code c'est plus que pas terrible
    Si, moi j'aime bien. Il fait ses allocations et libérations proprement. Bon il aurait pu faire saisir l'age avec le nom et surtout optimiser un peu plus les free mais il débute...

    Citation Envoyé par foetus Voir le message
    Code non testé, non compilé :
    Oui d'accord, tu fais un truc de pro. Mais bon, il débute quoi. (et il n'a pas appris les structures)...

    Citation Envoyé par nl.smart Voir le message
    ci-dessous le code après lecture et application de vos remarques, merci.
    Tu ne sors pas en erreur si un malloc de la boucle interne a planté.

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    #include <stdio.h>  // ok windows 32
    #include <stdlib.h> //
    #include <time.h>   //
    #include <string.h>
     
    int main() {
    	int nbre_personnes;
    	int bad=0;
    	size_t i; // La valeur d'une opération sizeof est de type size_t
     
    	char **ptr_prenom_personnes = NULL;
     
    	int *ptr_age_personnes = NULL;
     
    	printf("\n Combien de personnes sont ici présentes ? ");
    	scanf("%d", &nbre_personnes);
     
    	ptr_prenom_personnes = calloc(nbre_personnes, sizeof(*ptr_prenom_personnes));	// calloc met tous les octets du bloc à la valeur 0, malloc ne modifie pas la zone de mémoire
    	if (ptr_prenom_personnes == NULL) {
    		bad=1;
    		goto lol;
    	}
     
    	ptr_age_personnes = malloc(nbre_personnes * sizeof(int));
    	if (ptr_age_personnes == NULL) {
    		bad=2;
    		goto lol;
    	}
     
    	for (i = 0; i < nbre_personnes ; i++) {
    		ptr_prenom_personnes[i] = malloc(sizeof(*ptr_prenom_personnes[i]));
     
    		if (ptr_prenom_personnes[i] == NULL) {
    			bad=3;
    			goto lol;
    		}
     
    		printf("\n Quel est le prénom de la personne %i ? ", i + 1);
    		scanf("%s", ptr_prenom_personnes[i]);
    	}
     
    	for (i = 0; i < nbre_personnes ; i++) {
    		printf("\n Quel âge a %s ? ", ptr_prenom_personnes[i]);
    		scanf("%d", &ptr_age_personnes[i]);
    	}
     
    	for (i = 0; i < nbre_personnes ; i++) {
    		printf("\n %s a %d an%c ", ptr_prenom_personnes[i], ptr_age_personnes[i], ptr_age_personnes[i] > 1 ? 's' : ' ');
    	}
     
    	// libération de la mémoire allouée ci-après
    	lol: // goto reçu de la ligne 37
     
    	if (ptr_prenom_personnes != NULL) {
    		for (i = 0; i < nbre_personnes; i++)
    			free(ptr_prenom_personnes[i]); // libération de tous les prénoms renseignés
    		free(ptr_prenom_personnes);	// Oui, le mettre en dehors aurait fonctionné aussi mais puisque le bloc existe...
    	}
    	free(ptr_age_personnes);
     
    	printf("\n");
     
    	return bad == 0 ?EXIT_SUCCESS :EXIT_FAILURE;
    }
    Voilà. Tous les free() regroupés dans la même partie. Et on peut même si on veut détecter où ça plante...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  18. #18
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut
    Tu avances.

    Cette ligne pose problème !!! si sa fonctionne sa ne veut pas dire que c'est correct.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ptr_prenom_personnes[i] = malloc(sizeof(*ptr_prenom_personnes[i]));
    printf() pour t'aider à y voir clair. EX : printf("%ld\n", sizeof(*ptr_prenom_personnes[i]));
    à plaçé dans ton code avant la ligne du haut

  19. #19
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par nl.smart Voir le message
    Citation Envoyé par Proteiforme Voir le message
    Cette ligne pose problème !!! si sa fonctionne sa ne veut pas dire que c'est correct.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ptr_prenom_personnes[i] = malloc(sizeof(*ptr_prenom_personnes[i]));
    Exact. Et j'ai recopié bêtement (mais bon, 06h06 aussi )

    @nl.smart : Regarde attentivement ce que j'avais écrit hier => tab[i]=malloc(... * sizeof(*tab[i]));...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  20. #20
    Membre régulier
    Homme Profil pro
    Autres
    Inscrit en
    Août 2008
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Autres

    Informations forums :
    Inscription : Août 2008
    Messages : 39
    Points : 82
    Points
    82
    Par défaut
    Oui oui j'avais bien capter et je pensais qu'il réagirait sur cette ligne, mais il a juste recopier ta gestion d'erreur et ne s'est toujours pas préoccuper de l'allocation des chaines de caractères.

    Bien entendu mon commentaire sur la ligne 35 était pour nl.smart

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [x86-64] Allocation dynamique (malloc) et heap
    Par xion.luhnis dans le forum x86 32-bits / 64-bits
    Réponses: 5
    Dernier message: 23/10/2010, 19h23
  2. Probleme d'allocation malloc free
    Par cmoibal dans le forum Linux
    Réponses: 1
    Dernier message: 23/05/2007, 14h21
  3. Réponses: 8
    Dernier message: 20/11/2006, 00h13
  4. Pb d'allocation dynamique avec malloc
    Par Magicmax dans le forum C
    Réponses: 5
    Dernier message: 12/12/2005, 01h04
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo