29 votes

Insertion d'adresses dans des ensembles, la taille des ensembles est plus petite que prévu

Je reçois une taille de 1. Ne devrait-il pas être 4? J'insère les adresses d'entiers dans les ensembles.

 void func(set<int*>& s1, set<int*>& s2, int a)
{
    s1.insert(&a);
    s2.insert(&a);
}

int main()
{
    set<int*> s1, s2;

    int a = 1, b = 2, c = 3, d = 4;
    func(s1, s2, a);
    func(s1, s2, b);
    func(s1, s2, c);
    func(s1, s2, d);

    cout<<"  s1.size = "<<s1.size()<<"  s2.size = "<<s2.size()<<endl;
}
 

44voto

Holt Points 6689

&a à l'intérieur d' func est l'adresse du paramètre local en a, non pas à l'adresse de la variable d'origine (a, b, c ou d), dont:

  1. Peut prendre différents types de valeurs entre les différents appels d' func;
  2. Devient un pointeur non valide une fois que vous atteignez la fin de la portée dans laquelle a est déclaré (à la fin de l' func ici).

Dans votre cas, puisque vous ne faites rien, mais en l'appelant func 4 fois dans une ligne, l'adresse de ce paramètre arrive à ne pas changer, c'est pourquoi vous obtenez une taille de 1 (vous insérez le pointeur de même 4 fois).

Ce comportement est définie par l'implémentation (merci @Rakete1111) depuis définit aurez besoin de comparer des pointeurs invalides.

Accéder à l'élément pointé par s1 ou s2 (par exemple, **s1.begin()) est un comportement indéfini si.

28voto

songyuanyao Points 2265

Le paramètre a est passé par valeur, cela signifie que ce que vous êtes l'insertion est l'adresse du paramètre local copié à partir d'arguments. a sera construit à chaque fois lors de l' func est appelé, leurs adresses peuvent être identiques ou différents; rien n'est garanti.

Et il est intéressant de noter que le paramètre a seront détruites à sortir de la fonction, les pointeurs inséré deviendra de fait miroiter.

Vous devriez le faire passer par référence, alors les adresses des arguments (c'est à dire la variable a, b, c, d en main()) sera inséré. Ces adresses sont différentes, et ne se fait miroiter à l'intérieur du corps de l' main().

void func(set<int*>& s1, set<int*>& s2, int& a)
{
    s1.insert(&a);
    s2.insert(&a);
}

LIVE

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X