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 :

Taille d'un pointeur NULL


Sujet :

C++

  1. #1
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut Taille d'un pointeur NULL
    Bonsoir,

    Je me posais une petite question, est-ce qu'un pointeur sur NULL prend une quelconque place en mémoire, ou alors strictement rien du tout ?

    Merci

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Par défaut
    ça veut rien dire... un pointeur pointe sur une zone mémoire, ce qui prend de la place c'est la zone allouée, pas le pointeur. Que tu le fasse pointer vers NULL ou une zone réellement allouée, ça change rien.

  3. #3
    Membre éprouvé Avatar de BoudBoulMan
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 100
    Par défaut
    Ouais le pointeur n'occupera pas plus ou moins d'espace si tu changes la variable pointée. L'espace occupé correspond à l'espace requis pour identifier une adresse mémoire.

    Tu peux connaître la taille d'un pointeur grâce à un sizeof.
    J'obtiens une taille de 32 bits quelque soit la variable pointée.

    Tu peux faire le test grâce à ce programme:
    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
    #include <iostream>
    using namespace std;
     
    int main()
    {
    	int* pointeur = NULL;
    	cout << "pointeur = NULL: " << sizeof(pointeur)*8 << "bits" << endl;
     
    	int a=3;
            pointeur = &a;
    	cout << "pointeur = &a: " << sizeof(pointeur)*8 << "bits" << endl;
     
    	double b = 5.56;
    	double* pointeur2 = &b;
    	cout << "pointeur sur double: " << sizeof(pointeur2)*8 << "bits" << endl;
     
    	return 0;
    }
    Et j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    pointeur = NULL: 32bits
    pointeur = &a: 32bits
    pointeur sur double: 32bits

  4. #4
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Par défaut
    Ok merci .

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par BoudBoulMan Voir le message
    Tu peux faire le test grâce à ce programme:
    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
    #include <iostream>
    using namespace std;
     
    int main()
    {
    	int* pointeur = NULL;
    	cout << "pointeur = NULL: " << sizeof(pointeur)*8 << "bits" << endl;
     
    	int a=3;
            pointeur = &a;
    	cout << "pointeur = &a: " << sizeof(pointeur)*8 << "bits" << endl;
     
    	double b = 5.56;
    	double* pointeur2 = &b;
    	cout << "pointeur sur double: " << sizeof(pointeur2)*8 << "bits" << endl;
     
    	return 0;
    }
    sizeof est une constante de compilation, qui ne dépend pas de la valeur de son argument, juste de son type. En fait l'argument de sizeof n'est pas évalué. On peut donc faire sizeof une variable non-initialisée (très courant) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int i;
    cout << i ; // NON! comportement indéfini!
    cout << sizeof i; // OK
    On pourrait même faire des choses "interdites" dans sizeof :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout << sizeof (*(int*)0); // équivaut à sizeof (int)

  6. #6
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Et c'est d'ailleurs parce qu'il est évalué à la compilation qu'on le retrouve souvent dans des techniques de métaprogrammation.

  7. #7
    Membre Expert
    Avatar de Klaim
    Homme Profil pro
    Développeur de jeux vidéo
    Inscrit en
    Août 2004
    Messages
    1 717
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur de jeux vidéo
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 717
    Par défaut
    Excusez moi de changer de sujet mais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout << i ; // NON! comportement indéfini!

    ?

    Pourquoi?

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Klaim Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cout << i ; // NON! comportement indéfini!
    Ici i n'est pas initialisé.

    Lire une variable (d'un type de base) non initialisée donne un comportement indéfini, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int i, j;
    i = j; // comportement indéfini : j n'est pas initialisé
    Un pointeur qui a été désalloué ne peut plus être examiné non plus :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    int *p = new int;
    cout << p; // OK, imprime l'adresse de l'entier
    cout << *p; // comportement indéfini : l'entier n'as pas de valeur
    *p = 1;
    cout << *p; // OK, imprime 1
    int *q = p; // pas de pb
    delete p; // pas de pb
    // à partir de là, p ne contient plus une adresse valide
    cout << p; // comportement indéfini : lecture de p
    cout << q; // comportement indéfini : q n'est plus valide
    cout << p == q ? "égal" : "différent"; // comportement indéfini
    p = new int; // pas de pb
    q = p;
    cout << p == q ? "égal" : "différent"; // imprime égal
    Même sans utiliser delete, on peut avoir le cas : soit un pointeur vers une variable dont la durée de vie est terminée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int *p;
    {
        int i;
        p = &i;
        cout << p; // imprime l'adresse de i
    } // fin de la portée de i, fin de la durée de vie de i
    cout << p; // comportement indéfini : i n'existe plus
    Les seules choses qu'on peut faire avec une variable primitive non-initialisée, un pointer désalloué (avec free, delete, etc.), ou un pointeur contenait l'adresse d'une variable dont la durée de vie est terminée :
    • le "détruire" (terminer sa durée de vie, ce qui ne fait rien, les scalaires ont des destructeurs triviaux)
    • lui affecter une nouvelle valeur

    (unsigned char est particulier et échappe à la règle.)

  9. #9
    Membre éprouvé
    Avatar de NiamorH
    Inscrit en
    Juin 2002
    Messages
    1 309
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 1 309
    Par défaut
    Dites-moi si je me trompe mais, si on ne voit pas vraiment le comportement indéfini que pourrait provoquer le cout << d'un entier non initialisé (simple valeur non prédictible), on comprend mieux avec le simple cout << d'un pointeur non initialisé et déréférencé. Or le principe est bien le même : l'utilisation d'une variable T non initialisée.
    Maintenant, ce n'est peut-être pas ce que dis vraiment la norme, je ne l'ai pas lue.

    (unsigned char est particulier et échappe à la règle.)
    C'eut été intéressant de nous dire en quoi.

  10. #10
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Citation Envoyé par corrector
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    cout << p; // comportement indéfini : lecture de p
    cout << q; // comportement indéfini : q n'est plus valide
    cout << p == q ? "égal" : "différent"; // comportement indéfini
    Euh, là, je me permets de douter: Où est le problème tant qu'on ne déréférence pas le pointeur ?
    Est-il justement dans l'absence de garantie que le pointeur ne sera pas déréférencé ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Lire une variable (d'un type de base) non initialisée donne un comportement indéfini, par exemple :
    Faux !
    Lire cette valeur est totalement défini. C'est la valeure qui est totalement hasardeuse.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  12. #12
    Membre confirmé Avatar de babar63
    Homme Profil pro
    Développeur jeux vidéos/3d Temps réel
    Inscrit en
    Septembre 2005
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France

    Informations professionnelles :
    Activité : Développeur jeux vidéos/3d Temps réel

    Informations forums :
    Inscription : Septembre 2005
    Messages : 241
    Par défaut
    Lire cette valeur est totalement défini. C'est la valeure qui est totalement hasardeuse
    Cela doit surement dépendre de l'espace de travail utilisé en tout cas pour Visual Studio 2005 voilà les résultats pour : En mode debug :
    Run-Time Check Failure #3 - The variable 'j' is being used without being initialized.
    Et idem pour i bien sur, l'assertion permet cependant de continuer, les variables sont par défaut à -858993460.
    En mode release, les variables sont simplement initialisées à 0...

    C'est plutôt intéressant comme résultat... (je ne dit surtout pas qu'il faut le faire) mais quelle serait le comportement d'un telle code, cela dépend-t-il vraiment du compilateur et donc "pourrait" produire un code(/application) "stable" ou non? (Simple curiosité )

  13. #13
    screetch
    Invité(e)
    Par défaut
    En debug la pile est marqée par le code hexa #CC pour que les pointeurs pointent dans la moquette. En debug tu verras donc souvent des acces a #CCCCCCD0 qui est juste un offset de #CCCCCCCC

    en release la variable n'est _pas initialisée_ du tout. si tu recois 0 c'est que la precedente variable qui etait a cet endroit avait decidé d'y mettre 0. si elle avait decidé d'y mettre 72 tu etais fichu.

    Cela a par contre effet assez ennuyeux, c'est que les booleens sont toujours initialisé a #CC donc "true", et cela peut faire marcher un truc en debug mais pas en release. Quand je lis "ca marche en debug mais pas en release" je pense immediatement a une initialisation du mode debug (la pile, le tas) qui aurait mis un booleen a true, et je recommande de verifier l'initialisation des booléens. 3 fois ou cela c'est produit (avec comme seul diagnostique "ca marche en debug mais pas en release") et 3 fois la reponse etait un booléen initialisé comme un pied.

  14. #14
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par NiamorH Voir le message
    Dites-moi si je me trompe mais, si on ne voit pas vraiment le comportement indéfini que pourrait provoquer
    Je crois que tu ne saisis pas exactement le concept de comportement indéfini : c'est juste ce qui n'est pas défini! Ce n'est pas un comportement précis.
    La norme ne place aucune exigence sur l'implémentation concernant ce code.
    Le programme peut faire n'importe quoi, le compilateur sera toujours conforme.

    Citation Envoyé par NiamorH Voir le message
    Maintenant, ce n'est peut-être pas ce que dis vraiment la norme, je ne l'ai pas lue.
    La norme décrit la conversion de lvalue en rvalue :
    Citation Envoyé par draft C++, 4.1/1
    An lvalue (3.10) of a non-function, non-array type T can be converted to an rvalue. [...] If the object to which the lvalue refers is not an object of type T and is not an object of a type derived from T, or if the object is uninitialized, a program that necessitates this conversion has undefined behavior.
    (Ce n'est pas bien formulé d'ailleurs : il faut lire "or if T is a non-class type, and T is not char or unsigned char, and if the object is uninitialized, ...". Parce que là...)

    Citation Envoyé par NiamorH Voir le message
    C'eut été intéressant de nous dire en quoi.
    En gros tu peux les lire, mais la valeur n'est pas définie, et elle n'est même pas garantie d'être deux fois la même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    unsigned char c; // ou char
    cout << (int)c; // affiche un nombre entre 0 et UCHAR_MAX
    cout << (int)c; // affiche encore un nombre entre 0 et UCHAR_MAX, pas forcément le même
    cout << c == c ? "OK" : "étrange"; // affiche soit OK soit étrange
    Ceci dit, ça n'est écrit clairement nul part. C'est une inférence à partir de la norme et aussi "common wisdom". J'aurai du mal à le justifier formellement. (La norme n'est vraiment pas assez formalisée.)

  15. #15
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Faux !
    Lire cette valeur est totalement défini. C'est la valeure qui est totalement hasardeuse.
    D'accord, mais alors, défini où ça?

    (Chapitre et paragraphe s'il te plait.)

  16. #16
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Euh, là, je me permets de douter: Où est le problème tant qu'on ne déréférence pas le pointeur ?
    La valeur du pointeur ne doit plus être utilisée. Comme s'il était non-initialisé. Tu ne peux même pas recopier la valeur.

    Citation Envoyé par C++ draft, 3.7.3.2/4 [basic.stc.dynamic.deallocation]
    If the argument given to a deallocation function in the standard library is a pointer that is not the null pointer value (4.10), the deallocation function shall deallocate the storage referenced by the pointer, rendering invalid all pointers referring to any part of the deallocated storage.
    Citation Envoyé par Médinoc Voir le message
    Est-il justement dans l'absence de garantie que le pointeur ne sera pas déréférencé ?
    Non, copier, ou afficher un pointeur ne le déréférence pas, encore heureux.

  17. #17
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Citation Envoyé par corrector Voir le message
    D'accord, mais alors, défini où ça?

    (Chapitre et paragraphe s'il te plait.)
    Je n'ai plus le standard en tête, mais je suis sûr de moi.

    Imagine le code suivant :
    La 1er ligne créer une variable sur la pile sans lui affecté de valeur.
    Elle prend donc la valeur de ce qui se trouvait avant à cette place.
    Il n'y a pas de moyen de connaitre cette valeur. C'est dans ce sens que je dis que la valeur est indéfinie.

    Par contre la 2eme ligne, elle a un comportement totalement défini.Elle va t'afficher la valeur de a, qui peut être n'importe quoi.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  18. #18
    Membre éprouvé Avatar de BoudBoulMan
    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 100
    Par défaut
    Oui, le cout est tout à fait défini.

    Pour preuve, effectue-la deux fois, et tu obtiendras le même résultat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int a;
    cout << a << endl;
    cout << a << endl;  // affiche deux fois la même valeur

  19. #19
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Je n'ai plus le standard en tête, mais je suis sûr de moi.
    Moi si, lis mon autre réponse.

    Citation Envoyé par Davidbrcz Voir le message
    Imagine le code suivant :
    La 1er ligne créer une variable sur la pile sans lui affecté de valeur.
    Elle prend donc la valeur de ce qui se trouvait avant à cette place.
    C'est un comportement observable possible. Ce n'est pas le seul.

    Citation Envoyé par Davidbrcz Voir le message
    Il n'y a pas de moyen de connaitre cette valeur. C'est dans ce sens que je dis que la valeur est indéfinie.
    Sur certains systèmes, les entiers signés ne sont pas représentés en complément à 2 mais en complément à 1 ou en signe-magnitude. Parfois en signe-magnitude on considère que l'entier représentant 0 doit avoir un signe positif (signe 0). Si un entier représentant 0 a un signe négatif (représentation binaire un 1 suivit de zéros), c'est une erreur, et le processeur déclenche une exception. Si tu es sur un tel système, a peut avoir ce que la norme C appelle une "trap representation", un motif de bits qui n'a pas de sens pour le type de la variable. Tenter d'accèder à la valeur de la variable va alors déclencher une trap, une exception processeur. Qui peut se traduire par un signal et terminer brutalement (abort) le programme.

    Sur ce système, selon ce qui se trouvait avant à l'adresse de a, le programme peut planter ou pas. Ce qui est un autre exemple de comportement observable.

    Ces différents comportements sont permis par la norme puisque elle ne défini rien à propos du comportement d'un programme qui accède à une variable non initialisée. Ce qu'on appelle donc un comportement indéfini.

    Citation Envoyé par Davidbrcz Voir le message
    Par contre la 2eme ligne, elle a un comportement totalement défini.Elle va t'afficher la valeur de a, qui peut être n'importe quoi.
    Formellement (selon la sémantique définie par la norme C++), a n'a pas de valeur.

    Avant qu'on lui affecte une valeur, le compilateur n'est même pas obligé de lui allouer un emplacement rien qu'à elle dans la pile (ou un registre rien qu'à elle).

  20. #20
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2008
    Messages
    439
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 439
    Par défaut
    Citation Envoyé par BoudBoulMan Voir le message
    Oui, le cout est tout à fait défini.
    NON.

    Citation Envoyé par BoudBoulMan Voir le message
    Pour preuve, effectue-la deux fois, et tu obtiendras le même résultat.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    int a;
    cout << a << endl;
    cout << a << endl;  // affiche deux fois la même valeur
    Qu'est-ce que c'est censé prouver? Encore une fois : le comportement N'EST PAS défini. J'ai déjà cité la norme. J'ai déjà expliqué ce que cela signifiait.

    De plus, babar63 a donné un exemple de comportement très sympathique qui ne correspond pas à ce que tu dis.

    Je me demande si certains savent lire. Ou alors ils croient que leur expérience personnelle (limitée, forcément limité) leur donne la connaissance absolue.

    PS : tester (une, plusieurs, un million de fois) un programme ne garantit qu'il est correct. Par contre un test qui échoue démontre qu'il est bugué.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/03/2006, 09h13
  2. [PORT COM] RS485 et pointeur null...
    Par floanne dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 20/02/2006, 11h00
  3. get => pointeur null apres fermeture d'une sous-fenetre
    Par gorgonite dans le forum AWT/Swing
    Réponses: 15
    Dernier message: 11/02/2006, 21h42
  4. [Info][Mémoire] utilisée pour un pointeur null
    Par thomas_strass dans le forum Langage
    Réponses: 14
    Dernier message: 04/11/2004, 12h48
  5. Réponses: 4
    Dernier message: 06/04/2004, 21h57

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