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 :

malloc & characteres speciaux


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    384
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 384
    Par défaut malloc & characteres speciaux
    Bonjour,
    Je suis occupé de développer une petite application de recherche rapide pour retrouver des id, pseudo,... de joueurs que je stock dans un fichier.

    Pour ce faire j'ai fais 2 structures
    Code structure user : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct user{
    	int server;
    	int id;
    	char pseudo[30];
    	char pseudo_ingame[30];
    };
    Code structure index : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    struct index{
    	struct user user;
    	struct index *suivant;
    };
    J'essaye de faire un syteme avec allocation dynamique
    Code main : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    struct index *p14;
    UpdateIndexFichier(FICHIER14, &p14);
    Code fonction pour mettre a jour l'index : 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
    bool UpdateIndexFichier(char* Adress, struct index **pIndex)
    {
     
    	FILE *fichier;
    	bool status = false;
     
    	if((status = TestFile(Adress))){
    		if((fichier = fopen(Adress, "rb"))){
    			*pIndex = LoadUsers(fichier);
    			printf("%d\n", *pIndex->user.server);
    			fclose(fichier);	
    		}else
    			printf("ERREUR lors de l'ouverture du fichier %s\n", Adress);
    	}else
    		printf("Maj Index impossible: Ouverture de fichier impossible\n");
    	return status;
    }
    Code erroné dans la fonction juste au dessus : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d\n", *pIndex->user.server);
    Pourquoi le compilateur crie-t-il? comment résoudre?



    Code allocation en mémoire : 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
    struct index* LoadUsers(FILE *fichier)
    {
    	struct index tmpIndex, *start = NULL;
    	struct user *user;
     
    	//fread(&tmpIndex.user, sizeof(tmpIndex.user), 1, fichier);
     
    	tmpIndex.user.server = 14;
    	tmpIndex.suivant = NULL;
     
    	start = (struct index*)malloc(sizeof(tmpIndex));
     
    	if(start){
    		start = &tmpIndex;
    		if(DEBUG) printf("Malloc créé: adresse: %d", start);
    	}
    	else
    		printf("erreur lors de la création de mise en mémoire\n");
    	/*
    	while(!feof(fichier)){
     
    		for(cpt )
    	};
    	*/
    	return start;
    }
    Avec ce que je viens de vous donner petite question =>
    Comment puis-je vérifier que le malloc c'est bien passé? Puis-je de manière portable récupérer ça taille ? (D'apres mes recherches oui mais pas portable est-ce bien cela?)

    Et pour finir j'essaye de free le tout

    Code fonction pour free l'allocation : 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
    void FreeIndex(struct index *A)
    {
    	struct index *temp, *tempToFree;
    	/*free(A);*/
     
    	if(A){
    		temp = A;
    		do{
    			tempToFree = temp;
    			temp = temp->suivant;
    			free(tempToFree);
    		}while(temp != NULL);
    	}else
    		printf("vide");
     
    }

    Le programme plante lors du free pas trop d'idée pq je suis à l'aise avec les pointeurs mais c'est la première fois que j'utilise des pointeurs de pointeurs.
    Comment peut-on vérifier que le free c'est vraiment produit?

    De plus lors de l'affichage de mon index chaîné (actuellement 1 seul éléments pour les test) cela n'affiche pas le résultat voulu.

    j'aimerais un petit Feedback également sur les fonctions réalisés.

    J'ai également une question concernant les caractères spéciaux pour les pseudo comment puis-je les géré n'est pas trop casse gueule en C? et y à-t-il moyen de gérer ça de manière portable?

  2. #2
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    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 766
    Par défaut
    Citation Envoyé par Sparky95 Voir le message
    Le programme plante lors du free pas trop d'idée pq
    documentation free (<- lien cplusplus.com anglais)

    Notice that this function does not change the value of ptr itself, hence it still points to the same (now invalid) location.
    Si tu veux une traduction nécessite pas

  3. #3
    Membre expérimenté
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    384
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 384
    Par défaut
    oui je suis au courent qu'il ne changes pas le pointeur il désalloue juste la mémoire pointé par celui si
    c'est pour ça que je me demandais si l'on pouvaient récupérer la taille de la mémoire allouée et comment vérifier que cette mémoire ai bien été désalloué avant de "libérer le pointeur".
    j'étais sur tutoriel point qui donnes +/- les même info que cplusplus.com.
    J'ai peur de me balader parfois sur cplusplus.com de risque d'avoir du code C++ justement ^^

  4. #4
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    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 766
    Par défaut
    Citation Envoyé par Sparky95 Voir le message
    oui je suis au courent qu'il ne changes pas le pointeur il désalloue juste la mémoire pointé par celui si
    Donc si tu es au courant et comme tu cherches un plantage, explique moi cette partie de ton code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	free(A);
     
    	if(A) {
    		temp = A;
     
    // ...
     
    		temp = temp->suivant;

  5. #5
    Membre expérimenté
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    384
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 384
    Par défaut
    arf easy le free du dessus est un test de derniere minute avant de poster XD
    initialement il ne doit pas y être dans ma question:p
    Code en debug de dernière min avant d'avoir posté : 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
    void FreeIndex(struct index *A)
    {
    	struct index *temp, *tempToFree;
    	free(A);/*ligne que je n'avais pas mis dans mon code original. Je l'ai rajouté pendant les débug ^^*/
    /*	
    	if(A){
    		temp = *A;
    		do{
    			tempToFree = temp;
    			temp = temp->suivant;
    			free(tempToFree);
    		}while(temp != NULL);
    	}else
    		printf("vide");
    */	
    }

  6. #6
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Citation Envoyé par Sparky95 Voir le message
    Code erroné dans la fonction juste au dessus : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d\n", *pIndex->user.server);
    Pourquoi le compilateur crie-t-il? comment résoudre?
    Difficile de le savoir puisque tu ne nous transmets pas le message d'erreur en question, prends cette habitude ! Je penche tout de même pour le fait que *pIndex->user.server n'est pas de type int comme tu l'espérais, à cause d'une méconnaissance de l'ordre d'évaluation des opérateurs.


    Citation Envoyé par Sparky95 Voir le message
    Comment puis-je vérifier que le malloc c'est bien passé?
    C'est précisé dans sa documentation et probablement dans la section du cours qui traite de l'allocation dynamique également.


    Citation Envoyé par Sparky95 Voir le message
    Puis-je de manière portable récupérer ça taille ? (D'apres mes recherches oui mais pas portable est-ce bien cela?) [...] Comment peut-on vérifier que le free c'est vraiment produit?
    Non, (oui) et non, à ces trois questions. Le fait est que le langage part du principe que tu n'as jamais besoin de demander la taille, puisqu'à l'origine c'est toi qui fournit cette information !


    Ta fonction d'allocation / instanciation est inutilement compliquée. À quoi peut bien servir cette variable intermédiaire tmpIndex ?

    Et puis ça (j'ai simplifié) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct index tmpIndex,
                *start;
    start = malloc(sizeof tmpIndex);
     
    if (start)
        start = &tmpIndex;
     
    return start;
    Peux-tu nous détailler ce que fait ce morceau de code, ligne par ligne ? Et pourquoi ce n'est pas une bonne chose ?


    Citation Envoyé par Sparky95 Voir le message
    J'ai également une question concernant les caractères spéciaux pour les pseudo comment puis-je les géré n'est pas trop casse gueule en C? et y à-t-il moyen de gérer ça de manière portable?
    Autre sujet, autre thread.

  7. #7
    Membre expérimenté
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    384
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 384
    Par défaut
    Citation Envoyé par Matt_Houston Voir le message
    Difficile de le savoir puisque tu ne nous transmets pas le message d'erreur en question, prends cette habitude ! Je penche tout de même pour le fait que *pIndex->user.server n'est pas de type int comme tu l'espérais, à cause d'une méconnaissance de l'ordre d'évaluation des opérateurs.
    fonctions.c:89:26: error: request for member 'user' in something not a structure or union
    printf("%d\n", *pIndex->user.server);
    Citation Envoyé par Matt_Houston Voir le message
    Ta fonction d'allocation / instanciation est inutilement compliquée. À quoi peut bien servir cette variable intermédiaire tmpIndex ?

    Et puis ça (j'ai simplifié) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct index tmpIndex,
                *start;
    start = malloc(sizeof tmpIndex);
     
    if (start)
        start = &tmpIndex;
     
    return start;
    Peux-tu nous détailler ce que fait ce morceau de code, ligne par ligne ? Et pourquoi ce n'est pas une bonne chose ?




    Autre sujet, autre thread.
    Le but étant par la suite de récupérer les données dans un fichier
    mais vu que j'avais des bugg de malloc j'ai mis cette partie encore en cours de modif en commentaire
    j'ai donc créé le tmpIndex qui serrait une variable local pour récupérer les donnée dans le fichier
    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
    struct index* LoadUsers(FILE *fichier)
    {
    	struct index tmpIndex, *start = NULL;
    	struct user *user;
     
    	//fread(&tmpIndex.user, sizeof(tmpIndex.user), 1, fichier); Lecture du fichier
     
    	tmpIndex.user.server = 166;//mis pour tester dans le main si cela s'est bien enregistré => dans le code final je l'aurais supprimé
    	tmpIndex.suivant = NULL;//j'initialise le pointeur next a NULL
     
    	start = (struct index*)malloc(sizeof(tmpIndex));
     
    	if(start){   //if(start) vérifie si il y a eu malloc 
    		start = &tmpIndex;
    		if(DEBUG) printf("Malloc créé: adresse: %d", start); // le if(debug) un print de debug
    	}
    	else
    		printf("erreur lors de la création de mise en mémoire\n"); //else,... dans le cas ou le malloc c'est mal passé
    	/*
    		le while,... serra la boucle pour lire les éléments suivants dans le fichier que je devrai encore placer dans le if (start) par la suite
    	while(!feof(fichier)){
     
    		for(cpt )
    	};
    	*/
    	return start;
    }

  8. #8
    Membre expérimenté
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    384
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 384
    Par défaut
    Je viens de trouver pour le pointeur de pointeur de structure.
    Il fallait que je mets des parenthèses.

    Parcontre pourquoi est-ce que dans mon main j'obtiens une adress
    http://prntscr.com/jts9nu

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MajIndex14 = UpdateIndexFichier(FICHIER14, &p14);
    	printf("%d\n", p14->user.server);

  9. #9
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Prenons les choses dans l'ordre, ne construis pas la maison tant que la recette du mortier n'est pas au point.

    Tu n'as pas répondu aux questions posées plus haut :

    Citation Envoyé par Matt_Houston Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct index tmpIndex,
                *start;
    start = malloc(sizeof tmpIndex);
     
    if (start)
        start = &tmpIndex;
     
    return start;
    Peux-tu nous détailler ce que fait ce morceau de code, ligne par ligne ? Et pourquoi ce n'est pas une bonne chose ?

  10. #10
    Membre expérimenté
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    384
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 384
    Par défaut
    sisi je l'ai fais
    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
    struct index* LoadUsers(FILE *fichier)
    {
    	struct index tmpIndex, *start = NULL;
    	struct user *user;
     
    	//fread(&tmpIndex.user, sizeof(tmpIndex.user), 1, fichier); Lecture du fichier
     
    	tmpIndex.user.server = 166;//mis pour tester dans le main si cela s'est bien enregistré => dans le code final je l'aurais supprimé
    	tmpIndex.suivant = NULL;//j'initialise le pointeur next a NULL
     
    	start = (struct index*)malloc(sizeof(tmpIndex));
     
    	if(start){   //if(start) vérifie si il y a eu malloc 
    		start = &tmpIndex;
    		if(DEBUG) printf("Malloc créé: adresse: %d", start); // le if(debug) un print de debug
    	}
    	else
    		printf("erreur lors de la création de mise en mémoire\n"); //else,... dans le cas ou le malloc c'est mal passé
    	/*
    		le while,... serra la boucle pour lire les éléments suivants dans le fichier que je devrai encore placer dans le if (start) par la suite
    	while(!feof(fichier)){
     
    		for(cpt )
    	};
    	*/
    	return start;
    }
    donc ligne 1 "prototype je pense que c s'appel"
    3 et 4 déclaration structures
    6 mon futur fread en commentaire (serra l'initialisation de tmpindex)
    8 un test a supprimer dans le futur => modification de tmpIndex.user.server
    9 initialistation de tmpIndex.suivant

    11 initialisation pointeur start vers une zone mémoire mallocé
    13 vérifie si il y a eu malloc (vérifier si le pointeur pointe bien vers la zone mallocé)
    14 mise dans le malloc la strucuture index // pas sure


    26 retour de l'adresse du malloc

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    start = (struct index*)malloc(sizeof(tmpIndex));
     
    	if(start){   //if(start) vérifie si il y a eu malloc 
    		start = &tmpIndex;
    Tu écris litérallement : alloue de la mémoire, et si tu as réussi pointe vers cette donnée interne.
    Entraînant au passage une fuite mémoire.

    Donc soit ta fonction retourne NULL si l'allocation échoue, soit elle retourne un pointeur invalide à la sortie de la fonction. En gros dès que tu l'appelles, au mieux tu ne retournes rien, soit t'as une fuite et retournes un pointeur invalide et un crash (ou autre comportement indéterminé) plus loin.

    Si tu veux vraiment mise dans le malloc la strucuture index, tu veux affecter des données à la zone pointée, et non au pointeur, et donc *start = tmpIndex;, ou memcpy(start, &tmpIndex, sizeof(tmpIndex));.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  12. #12
    Membre expérimenté
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    384
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 384
    Par défaut
    cv je comprends mieux bête faut :p
    Merci

    Donc si je fais ceci je ne risque pas d'avoir de problemes mémoire?
    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
    int main(void){
    	struct index *p14;
    	bool MajIndex14;
     
    	MajIndex14 = UpdateIndexFichier(FICHIER14, &p14);
     
    	printf("%d\n", p14->user.server);
     
    	FreeIndex(p14);
        return 0;
    }
     
    bool UpdateIndexFichier(char* Adress, struct index **pIndex)
    {
    	FILE *fichier;
    	bool status = false;
     
    	if((status = TestFile(Adress))){
    		if((fichier = fopen(Adress, "rb"))){
    			*pIndex = LoadUsers(fichier);
    			fclose(fichier);	
    		}else
    			printf("ERREUR lors de l'ouverture du fichier %s\n", Adress);
    	}else
    		printf("Maj Index impossible: Ouverture de fichier impossible\n");
    	return status;
    }
     
    struct index* LoadUsers(FILE *fichier)
    {
    	struct index tmpIndex, *start = NULL;
     
    	tmpIndex.user.server = 166;
    	tmpIndex.suivant = NULL;
     
    	start = (struct index*)malloc(sizeof(tmpIndex));
     
    	if(start)
    		*start = tmpIndex;
    	else
    		printf("erreur lors de la création de mise en mémoire\n");
     
    	return start;
    }
     
    void FreeIndex(struct index *A)
    {
    	struct index *temp, *tempToFree;
     
    	if(A){
    		temp = A;
    		do{
    			tempToFree = temp;
    			temp = temp->suivant;
    			free(tempToFree);
    		}while(temp != NULL);
    	}else
    		printf("vide");
     
    }
    auriez vous faient comme cela? ou comment auriez vous faient votre/vos fonctions?

  13. #13
    Membre expérimenté
    Avatar de Sparky95
    Homme Profil pro
    Full Stack (web) developer
    Inscrit en
    Décembre 2016
    Messages
    384
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : Belgique

    Informations professionnelles :
    Activité : Full Stack (web) developer
    Secteur : Transports

    Informations forums :
    Inscription : Décembre 2016
    Messages : 384
    Par défaut
    Citation Envoyé par Bousk Voir le message
    Entraînant au passage une fuite mémoire.
    Dans le cas ou l'utilisateur arrête le programme brutalement style un "Ctrl+C".
    Que ce passe-t-il avec la mémoire alloué?
    Est-elle libéré? je suppose que non comment gérer des cas comme celui la?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 11/07/2006, 22h47
  2. Erreur de sgmentation avec malloc
    Par simonm dans le forum C
    Réponses: 5
    Dernier message: 27/02/2003, 08h29
  3. Réponses: 4
    Dernier message: 03/12/2002, 16h47
  4. delphi XML / HTML caractéres speciaux !
    Par adem dans le forum EDI
    Réponses: 2
    Dernier message: 29/08/2002, 17h48

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