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 :

Probleme avec realloc et free


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Juillet 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 12
    Par défaut Probleme avec realloc et free
    Bonjour tout le monde, je suis lycéen et en stage, au cours de ce stage, j ai été chargé de développer un petit programme, qui doit ouvrir un fichier (.wbp), récupérer certaines valeurs inscrites dedans, et les recopier a la suite dans un autre fichier (.keyframe).
    Le tout devant être le plus flexible possible.

    Puisque je ne sais pas combien de valeurs je vais récupérer, j'ai appris sur le tas (en lisant les docs) a utiliser malloc, calloc, realloc et free, et je pense avoir compris le concept.

    Cependant, lorsque je test mon programme, realloc me renvoie systématiquement un pointeur NULL, ce qui me bloque en plein milieu, et quand je passe les realloc, c'est free qui refuse de me renvoyer un pointeur NULL

    Voici le code:
    Mes declarations de variables et define:
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #define MP "MarkerPosition" 
    #define tcache 64           
    #define tnom 50             
     
    __________________
     
    int main (int argc, char *argv[])
    {
        /*
        int *:
        -tabPos: Tableau Positions, tableau dynamique contenant les positions (MarkerPositions)
        -argv:Nom complet des fichiers wbp a la suite
        -argc:Nombre de fichiers a ouvrir +1
     
        unsigned int:
        -pkmn: touche perso & compteur de .wbp fini (pour la boucle principale)
        -nbrPos: Compteur de positions trouvées
        -end : Sert lors de la recuperation des positions, a detecter quand les chaines recupérées ne sont plus valide afin de sortir de la boucle.
     
        char:
        -nom[]: Nom du fichier .wbp a ouvrir, puis du .keyframe a creer
        -cache[]: Sert pour retrouver les "MarkerPositionX" dans le .wbp
     
        FILE*:
        -wbp: Fichier wbp
        -kf: Fichier KeyFrame
        */
     
        int *tabPos=NULL;
        unsigned int pkmn=1, nbrPos=0, end = 0, curseur=0;
        char nom[tnom]={0}, cache[tcache]={0};
        FILE* wbp=NULL;
        FILE* kf=NULL;
    Ici mon utilisation de calloc (seule fonction fonctionnant):

    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
     
    int * memoryCreate ()       //Allouer la memoire
    //VARIABLES
         //I: /
         //O: tabPos (tableau dynamique)
    {
        int * tabPos = NULL;
        int bcl=0;
        //Allouer tabPos (une case de memoire) avec calloc (pour la mettre a 0)
        printf("-Creation du tableau de memoire...");
        do
        {
            tabPos = calloc (sizeof(int),1);
            bcl=bcl+1;
            if (tabPos==NULL && bcl>3)  //Si tabPos n'a toujours pas été alloué au bout de trois tentatives
            {
                printf("FAIL\nAllocation de mémoire impossible\nErreur %d\n__________\n", errno);
                exit(EXIT_FAILURE); //Indiquer l erreur et sortir du programme
            }
        }while (tabPos == NULL);  //Tant que la memoire n'a pas été alloué
        printf("OK\n");
        return tabPos;
    }
    Ici la fonction utilisant realloc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    int * tabUp (int* tabPos, int nbrPos)
    {
        int * save=NULL;
        printf("Reallocation...");
        //Reallouer tabPos avec une case de plus
        do
        {
            save = (int *) realloc (tabPos, nbrPos * sizeof(int));
        }while (save == NULL);
        printf("OK\n");
        return (int *) save;
    }
    Et mon free:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    //Liberer la memoire
                printf("Liberation de la memoire...");
                while (tabPos!=NULL)
                {
                    free(tabPos);
                }
                printf("OK\n");
    Je travaille sous Windows avec Code::Blocks, les seuls messages d'erreurs sont deux bout de codes déclaré inatteignable, mais n'ayant aucun lien avec ces fonctions (l'un est le return 0; precedé de exit(EXIT_SUCCESS);, vu que C::B rale sans son return 0;, et l'autre est dans une tout autre fonction, un if suivant une boucle, je ne vois pas pourquoi il me le déclare inatteignable, mais cette partie la fonctionnant, ce n'est pas ma priorité...

    TLR: Je n'arrive pas a utiliser realloc correctement, j'ai beau comparer a la doc je ne trouve pas mon erreur: que faire?

  2. #2
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Sur le free() :
    free(tabPos);ne peut pas modifier tabPos, donc à fortiori le mettre à NULL. Donc simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    //Liberer la memoire
      printf("Liberation de la memoire...");
      free(tabPos);
      tabPos = NULL ; // si besoin
      printf("OK\n");
    Sur memoryCreate () :
    - Si l'allocation a échoué, il n'y a pratiquement aucune chance qu'elle réussisse ensuite presque immédiatement, donc la boucle n'a pas franchement d'efficacité.

    Sur tabUp() :
    - Même remarque que pécédemment.
    - Il n'y a aucune raison que le realloc() échoue pour des tailles raisonnables. Il faut donc vérifier que
    * le paramètre tabPos correspond bien à une valeur retournée par malloc()/calloc()/realloc()
    * le paramètre nbrPos est strictement positif et de valeur "raisonnable".
    - Note : les cast en (int*) sont superflus.

  3. #3
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Bonjour,

    Realloc ne s'utilise pas comme ca :
    Le mettre dans une boucle ne sert a rien
    En general, on re-utilise le meme buffer en cas de succes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    save = realloc (tabPos, ...)
     
    if (save != NULL)
    {
      tabPos = save;
    }
    else
    {
      traitement de l'erreur;
    }
    Bien sur, pour cela, il faut pouvoir modifier le pointeur, et donc passer en parametre a ta fonction un int **.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  4. #4
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Juillet 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 12
    Par défaut
    Citation Envoyé par diogene Voir le message
    Sur le free() :
    free(tabPos);ne peut pas modifier tabPos, donc à fortiori le mettre à NULL. Donc simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    //Liberer la memoire
      printf("Liberation de la memoire...");
      free(tabPos);
      tabPos = NULL ; // si besoin
      printf("OK\n");
    Arg le con, effectivement free ne retourne aucune valeur
    Est ce qu il y a un moyen de verifier que la libération a été effectué?

    Citation Envoyé par diogene Voir le message
    Sur memoryCreate () :
    - Si l'allocation a échoué, il n'y a pratiquement aucune chance qu'elle réussisse ensuite presque immédiatement, donc la boucle n'a pas franchement d'efficacité.
    Tellement évident que je n y avait pas pensé >_>
    Je vais modifier ca et renvoyer une valeur d'erreur si l allocation ne marche pas

    Citation Envoyé par diogene Voir le message
    Sur tabUp() :
    - Même remarque que précédemment.
    - Il n'y a aucune raison que le realloc() échoue pour des tailles raisonnables. Il faut donc vérifier que
    * le paramètre tabPos correspond bien à une valeur retournée par malloc()/calloc()/realloc()
    * le paramètre nbrPos est strictement positif et de valeur "raisonnable".
    - Note : les cast en (int*) sont superflus.
    Je viens de verifier, je peux certifier qu'il s'agit bien d'une valeur de retour de calloc
    nbrPos est égal au nombres de valeur déjà recupéré +1, et lorsque le programme tombe dans une boucle infinie, il est égal a 2

    Citation Envoyé par Bktero Voir le message
    Je n'ai pas compris grand chose à ce paragraphe. Il faut savoir que exit() quitte le programme donc si un return suit un exit(), il ne sert à rien et ne sera jamais exécuté.
    En fait, C::B se met a hurler si le main ne se finit pas par return 0;, donc pour éviter de le mettre et l'enlever sans arrêt, je le laisse et me prend donc un warning, j'ai juste dit ca pour montrer quelles sont les erreur renvoyé par le compilateur

    Citation Envoyé par gangsoleil Voir le message
    En general, on re-utilise le meme buffer en cas de succes :
    Bon, je vais refaire mes fonction, je vois que mes boucles posent toutes problèmes

    Citation Envoyé par gangsoleil Voir le message
    Bien sur, pour cela, il faut pouvoir modifier le pointeur, et donc passer en parametre a ta fonction un int **.
    int ** --> Tableau de pointeur?
    Si j a bien compris on ne les utilise que lorsque l'on veux faire des tableaux dynamique a deux dimension nan?

  5. #5
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Juillet 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 12
    Par défaut
    (Je sais que le double post c'est mal, mais je pense qu un edit ne fera qu'agrandir inutilement un post déjà très (trop?) grand)

    Bon, j'ai corrigé mon code grâce a vous (les boucles sont remplacé par des renvoi de code d'erreur, j'ai adapté le main pour les traiter, j'ai résolu les warnings de code inatteignable...) et je vous remercie déjà pour cela

    Je viens de tester, mes reallocations successives se font sans problème pendant 3/4 tour de boucle, et d'un coup me saute a la gueule, est-ce que errno contient quelque chose en cas d'erreur sur realloc?

    Autre problème, mon free(tabPos) me fait planter le programme et Windows m'affiche son habituel message inutile, j'avoue être perdu.

    Voici les nouvelles fonctions et les parties utile de mon main:
    La partie utilisant tabUp:
    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
     
    //Incrementer nbrPos
                            nbrPos=nbrPos+1;
     
                            //Augmenter la taille de tabPos
                            save=tabUp(tabPos, nbrPos);
                            //Si la reallocation se passe sans probleme
                            if (save!=NULL && save!= (int *)-1)
                            {
                                //Valider la reallocation et continuer
                                tabPos=save;
                            }
                            //Sinon
                            else
                            {
                                printf("/!\\Une erreur dans l'allocation s'est produite, les données acquises sont gardees, mais il peut manquer les données suivantes\n");
                                //Sortir de la boucle sans modifier tabPos, et en remettant nbrPos a sa valeur precedente pour eviter des erreurs
                                nbrPos=nbrPos-1;
                                end=-1;
                            }
    La partie contenant le free, le premier printf s'affiche, le second n'en a pas le temps, ce qui me laisse penser que c'est le free qui fait tout planter.
    Pour quelles raisons un free peut faire planter un programme?
    :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    //Liberer la memoire
            printf("Liberation de la memoire...");
            free(tabPos);
            //Vraiment aucun moyen de verifier si tout c'est bien passé?
            tabPos=NULL;
            printf("OK\n");
    tabUp, fonctionne environ 4 fois avant de ne plus reallouer, et je suis sur que tabPos correspond bien a mon allocation par calloc, je vais verifier en continu toute les valeurs de nbrPos, mais ce serait surprenant qu il dépasse (nombre de valeurs recupéré + 1):
    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
     
    int * tabUp (int* tabPos, int nbrPos)
    {
        int * save=NULL;
        printf("Reallocation...");
        //Reallouer tabPos avec une case de plus
        save = (int *) realloc (tabPos, nbrPos * sizeof(int));
        if (save == NULL)
        {
            printf("FAIL\n");
            return (int *) -1;
        }
        printf("OK\n");
        return (int *) save;
    }
    TL: DR:
    -Mon free(tabPos) me fait planter le programme et afficher un message d'erreur windows sans informations, pourtant je crois respecter la doc
    -Mes realloc plantes abruptement après avoir réussi plusieurs fois
    -Est ce qu il y a moyen de verifier que free() a fonctionné?
    -Est ce que realloc () inscrit quelque chose d utilisable dans errno? (La doc me laisse perplexe vu qu elle ne mentionne pas du tout errno)
    -Meme question pour free

  6. #6
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Par défaut
    Que penses-tu du code suivant :
    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
     
    int tabUp (int** tabPos, int nbrPos)
    {
        int * save=NULL;
        int return_value;
     
        printf("Reallocation...");
        //Reallouer tabPos avec une case de plus
        errno = 0;
        save = realloc (*tabPos, nbrPos * sizeof(int));
     
        if (save == NULL)
        {
            printf("Realloc failure. Errno : %d, %s\n", errno, strerror(errno) );
            return_value = -1;
        }
        else
        {
            printf("OK\n");
            *tabPos = save;
            return_value = 0; /* Je ne sais pas ce que tu veux comme valeur de retour */
        }
     
        return return_value;
    }

    Citation Envoyé par DrakaSAN Voir le message
    -Est ce qu il y a moyen de verifier que free() a fonctionné?
    -Est ce que realloc () inscrit quelque chose d utilisable dans errno? (La doc me laisse perplexe vu qu elle ne mentionne pas du tout errno)
    free ne peut pas ne pas fonctionner.
    En cas d'erreur de malloc, la valeur retournee est NULL, mais la zone memoire prealablement allouee est toujours valide. Pour errno, je ne sais pas, mais dans le doute, tu peux toujours l'afficher.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  7. #7
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Juillet 2012
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Lycéen
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2012
    Messages : 12
    Par défaut
    Citation Envoyé par gangsoleil Voir le message
    Que penses-tu du code suivant :
    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
     
    int tabUp (int** tabPos, int nbrPos)
    {
        int * save=NULL;
        int return_value;
     
        printf("Reallocation...");
        //Reallouer tabPos avec une case de plus
        errno = 0;
        save = realloc (*tabPos, nbrPos * sizeof(int));
     
        if (save == NULL)
        {
            printf("Realloc failure. Errno : %d, %s\n", errno, strerror(errno) );
            return_value = -1;
        }
        else
        {
            printf("OK\n");
            *tabPos = save;
            return_value = 0; /* Je ne sais pas ce que tu veux comme valeur de retour */
        }
     
        return return_value;
    }
    Je ne comprend pas pourquoi tu met int** et non int*?
    int ** c'est un tableau a deux dimensions, ce que je veux est juste un tableau contenant une suite de valeur, donc une seule dimension
    (Ou alors faut que je reprenne toute les docs que j ai trouvé a zero et tout relire et tester)

    Je test ça dès que j'ai le temps (je ne fais malheureusement pas que du code) et j'edit pour te dire ce que ça donne

    EDIT: Pour la valeur de retour, tu a bien fait de me faire remarquer que je ne l'ai pas indiqué
    tabUp doit renvoyer tabPos réaloué

    Citation Envoyé par gangsoleil Voir le message
    free ne peut pas ne pas fonctionner.
    Bon bah comme ca je suis fixé x)
    Mais dans ce cas pourquoi windows plante après entre un free et un printf?

    Citation Envoyé par gangsoleil Voir le message
    En cas d'erreur de malloc, la valeur retournee est NULL, mais la zone memoire prealablement allouee est toujours valide. Pour errno, je ne sais pas, mais dans le doute, tu peux toujours l'afficher.
    Je suppose que tu voulais dire realloc et non malloc, et j'arrive déja a recuperer le fait qu il y ait une erreur, ce que je voudrait, c'est un moyen de savoir quel est l'erreur.

    Je vais voir si il y a une doc sur errno, ils doivent bien dire par quelles fonctions il est modifié.

  8. #8
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    free(p) peut faire planter si
    - p est une valeur non NULL qui n'a pas été obtenue par malloc() et compagnie (ou a été modifiée ensuite évidemment)
    - la zone pointée par p a déjà été libérée par un free()

    La fonction tabUp() ne semble pas en cause, mais pourquoi pas simplement
    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
    int * tabUp (int* tabPos, int nbrPos)
    {
       return realloc (tabPos, nbrPos * sizeof *tabPos);
    }
     
    ....
       //Augmenter la taille de tabPos
       printf("Reallocation...");           // pour tester
       save=tabUp(tabPos, nbrPos+1);
       //Si la reallocation se passe sans probleme
       if (save!=NULL)
       {
          //Valider la reallocation et continuer
          tabPos=save;
          nbrPos++;
          printf("Reallocation OK\n");      // pour tester
       }
       //Sinon
       else
       {
           printf("/!\\Une erreur dans l'allocation s'est produite, les données acquises sont gardees, mais il peut manquer les données suivantes\n");
           //Sortir de la boucle sans modifier tabPos, et en remettant nbrPos a sa valeur precedente pour eviter des erreurs
           end=-1;
       }
    L'erreur est sans doute ailleurs. Donc, il faudrait plutôt montrer plus de code dans la partie du programme qui utilise ces fonctions.

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 492
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 492
    Billets dans le blog
    1
    Par défaut
    J'ai testé ta fonction memorycreate, elle est en sortie en succès. idem pour tabUp.

    Free ne met pas le pointeur à NULL, il libère juste l'espace mémoire. C'est à toi de le remettre à NULL.

    Si malloc / calloc / realloc échoue, c'est en général parce qu'il n'y a plus de mémoire disponible. Ca ne sert donc à rien de les appeler en boucle puisqu'il y a peu de chance que de la mémoire se libère aussi rapidement que cela. Il faudrait éventuellement attendre un peu.

    Je travaille sous Windows avec Code::Blocks, les seuls messages d'erreurs sont deux bout de codes déclaré inatteignable, mais n'ayant aucun lien avec ces fonctions (l'un est le return 0; precedé de exit(EXIT_SUCCESS);, vu que C::B rale sans son return 0;, et l'autre est dans une tout autre fonction, un if suivant une boucle, je ne vois pas pourquoi il me le déclare inatteignable, mais cette partie la fonctionnant, ce n'est pas ma priorité...
    Je n'ai pas compris grand chose à ce paragraphe. Il faut savoir que exit() quitte le programme donc si un return suit un exit(), il ne sert à rien et ne sera jamais exécuté.

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

Discussions similaires

  1. probleme avec realloc
    Par adrien1 dans le forum Débuter
    Réponses: 1
    Dernier message: 07/10/2009, 21h20
  2. Réponses: 5
    Dernier message: 05/12/2006, 14h04
  3. [Free Pascal] Problème avec 'str'
    Par TheBigMac dans le forum Free Pascal
    Réponses: 1
    Dernier message: 12/04/2006, 21h56
  4. [Free Pascal] Problème avec delay
    Par Cedrun dans le forum Free Pascal
    Réponses: 3
    Dernier message: 27/01/2006, 17h53
  5. [Debutant]Probleme avec un realloc
    Par Jabbal'H dans le forum C
    Réponses: 21
    Dernier message: 11/01/2006, 15h25

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