web-dev-qa-db-fra.com

Comment comparer les pointeurs?

Supposons que j'ai 2 pointeurs:

int *a = something;
int *b = something;

Si je veux les comparer et voir s'ils pointent au même endroit, est-ce que (a == b) fonctionne?

62
Joey Franklin

Oui, c’est la définition de l’égalité de pointeur: ils désignent tous deux le même emplacement (ou sont alias de pointeur )

50

Pour un peu de faits, voici le texte pertinent du cahier des charges

Opérateur d'égalité (==,! =)

Les pointeurs sur des objets du même type peuvent être comparés aux résultats escomptés «intuitifs»:

À partir de § 5.10 de la norme C++ 11:

Pointeurs du même type (après les conversions de pointeur) peuvent être comparés pour l'égalité. Deux pointeurs du même type se comparent égaux si et que si elles sont toutes deux nulles, les deux pointent vers la même fonction ou représentent la même adresse (3.9.2).

(laissant de côté les détails sur la comparaison des pointeurs vers les membres et/ou les constantes du pointeur nul - ils continuent dans la même ligne de 'Do What I Mean' ':)

  • [...] Si les deux opérandes sont nuls, ils se comparent égaux. Sinon, si un seul est nul, ils comparent inégale. [...] 

La mise en garde la plus "évidente" concerne les logiciels virtuels, et elle semble être la chose logique à attendre aussi:

  • [...] s'il s'agit d'un pointeur sur une fonction membre virtuelle, le résultat est non spécifié. Sinon, ils comparez égal si et seulement si elles se référaient au même membre du même objet le plus dérivé (1.8) ou le même sous-objet s’ils ont été déréférencés avec un objet hypothétique du type de classe associé. [...] 

Opérateurs relationnels (<,>, <=,> =)

À partir de § 5.9 de la norme C++ 11:

Les pointeurs sur des objets ou des fonctions du même type (après conversions de pointeur) peuvent être comparés, avec un résultat défini comme suit:

  1. Si deux pointeurs p et q du même type pointent vers le même objet ou function, ou les deux pointent un après la fin du même tableau, ou sont les deux null, alors p<=q et p>=q donnent tous les deux true et p<q et p>q donnent false.
  2. Si deux pointeurs p et q du même type pointent sur des objets différents qui ne sont pas membres du même objet ou sur des éléments du même tableau ou sur des objets différents fonctions, ou si une seule d'entre elles est nulle, les résultats de p<q,p>q,p<=q, et de p>=qne sont pas spécifiés.
  3. Si deux pointeurs pointent vers des membres de données non statiques du même objet ou vers sous-objets ou éléments de tableau de ces membres, de manière récursive, le pointeur sur le le membre déclaré plus tard se compare plus grand à condition que les deux membres aient le même contrôle d'accès (article 11) et à condition que leur classe ne soit pas un syndicat.
  4. Si deux pointeurs pointent vers des données non statiques membres du même objet avec contrôle d'accès différent (Article 11), le résultat n'est pas spécifié.
  5. Si deux pointeurs pointent vers des membres de données non statiques du même objet d'union, ils se comparent égaux (après conversion en void*, si nécessaire). Si deux pointeurs pointez sur des éléments du même tableau ou au-delà de la fin du tableau, le le pointeur sur l’objet dont l’indice est élevé compare plus haut.
  6. Les autres comparaisons de pointeurs ne sont pas spécifiées.

Donc, si vous aviez:

int arr[3];
int *a = arr;
int *b = a + 1;
assert(a != b); // OK! well defined

Correcte aussi:

struct X { int x,y; } s;
int *a = &s.x;
int *b = &s.y;
assert(b > a); // OK! well defined

Mais cela dépend de la something dans votre question:

int g; 
int main()
{
     int h;
     int i;

     int *a = &g;
     int *b = &h; // can't compare a <=> b
     int *c = &i; // can't compare b <=> c, or a <=> c etc.
     // but a==b, b!=c, a!=c etc. are supported just fine
}

Bonus: qu'y a-t-il d'autre dans la bibliothèque standard?

§ 20.8.5/8: "Pour les modèles greater, less, greater_equal et less_equal, les spécialisations de tout type de pointeur génèrent un ordre total, même si les opérateurs intégrés <, >, <=, >= ne pas."

Ainsi, vous pouvez globalement commander n’importe quel void* impair tant que vous utilisez std::less<> et amis, pas nu operator<.

86
sehe

L'opérateur == sur les pointeurs comparera leur adresse numérique et déterminera donc s'ils pointent sur le même objet. 

18
JaredPar

Pour résumer. Si nous voulons voir si deux pointeurs pointent vers le même emplacement mémoire, nous pouvons le faire. De même, si nous voulons comparer le contenu de la mémoire pointée par deux pointeurs, nous pouvons également le faire. Rappelez-vous d’abord de les déréférencer.

Si nous avons 

int *a = something; 
int *b = something;

qui sont deux pointeurs du même type on peut:

Comparer l'adresse mémoire:

a==b

et comparer le contenu:

*a==*b
13
ldgorman

Code simple pour vérifier les alias de pointeur:

int main () {
    int a = 10, b = 20;
    int *p1, *p2, *p3, *p4;

    p1 = &a;
    p2 = &a;
    if(p1 == p2){
        std::cout<<"p1 and p2 alias each other"<<std::endl;
    }
    else{
        std::cout<<"p1 and p2 do not alias each other"<<std::endl;
    }
    //------------------------
    p3 = &a;
    p4 = &b;
    if(p3 == p4){
        std::cout<<"p3 and p4 alias each other"<<std::endl;
    }
    else{
        std::cout<<"p3 and p4 do not alias each other"<<std::endl;
    }
    return 0;
}

Sortie:

p1 and p2 alias each other
p3 and p4 do not alias each other
1
Pankaj Kumar Thapa