2010-12-11 13 views
2

S'il vous plaît jeter un oeil à mes fichiers source, ils sont un peu trop longtemps pour les poster ici:C++: ce pointeur écrasé

X11Painter.cpp: http://pastebin.com/gu4SrHUr

X11Painter.h: http://pastebin.com/3ktp1Fvn

Le comportement de cette classe est à mon avis très étrange.

Je vais avoir le cas de test suivant:

#include "X11Painter.h" 
int main() 
{ 
    X11Painter p ; 
    p.show(); 
} 

avec la Compiler ligne

g++ -O0 -g -o test2 test2.cpp X11Painter.cpp -lX11 -lXfixes -lXinerama 

et simplement exécuter effectue les opérations suivantes:

this->some_test=1234 
this->screen:0 
1:: this->display='0x8b73008'; this->window='77594625' 
width: 3200 
0xbff91bdc 
this->some_test=1234 
this->some_test=3682292 
Segmentation fault 

Je suis essayer de mapper la fenêtre X11 en X11Painter::show()

Lorsque j'ai commencé à étudier pourquoi X11Painter.cpp: 83 est segfaulting, j'ai découvert que la plupart des variables sont remplacées et complètement différentes dans show() qu'elles ne l'étaient dans le constructeur.

Je mets le int some_test pour voir ce qui se passe. Pourquoi diable la valeur change-t-elle? Si printf("%p\n", this), le pointeur change également. Je pense que quelque part, le pointeur est écrasé. Mais pourquoi cela se passe-t-il? Le débogage avec ddd m'a indiqué que this-> some_value est modifié juste en quittant le constructeur.

Faire un test court avec un testclass (classe avec un constructeur public, une méthode publique et une variable privée) fonctionne sans aucun problème.

Est-ce que quelqu'un a une idée de pourquoi cette chose étrange se produit? Je sais ce qu'il advient des variables qui se trouvent sur la pile, mais nous en sommes toujours là ...

Est-ce que cela peut être lié aux bibliothèques X11?

+0

Vous devriez rendre vos fichiers source suffisamment petits pour être publiés ici. Cela a deux avantages: premièrement, plus de gens les verront; deuxièmement, en les rendant plus petits, vous pourriez trouver vous-même la source du problème. – TonyK

Répondre

12

Dans votre constructeur parameterless, vous le faites

X11Painter::X11Painter() 
{ 
    X11Painter(-1); 
} 

Ce ne fait pas ce que vous pensez qu'il est en train de faire, car il n'y a pas de constructeur Enchaînement en C++. Ce que fait le code ci-dessus est la construction d'un objet temporaire X11Painter, appelant l'autre constructeur pour cet objet temporaire, mais n'initialisant réellement rien dans l'objet que vous voulez construire.

Pour résoudre ce problème tout en conservant le même problème, supprimez votre constructeur parameterless et dans votre fichier .h déclarer l'autre constructeur comme

X11Painter(int screenno = -1); 

Ce sera par défaut l'argument screenno à -1 si vous ne fournissez pas un.

+4

+1 pour signaler une erreur, mais deux remarques: 1. Dans la prochaine version C++, il y aura un chaînage de constructeur, quoique avec une syntaxe différente. 2. Le constructeur devrait être déclaré explicite, car une conversion implicite de 'int' en' X11Painter' n'a aucun sens. – Philipp

+0

Philipp: Que voulez-vous dire exactement par la 2ème remarque? Où est une conversion de int à X11Painter? merci – Atmocreations

+1

@Atmocreations: Si vous avez un constructeur à un paramètre, comme dans ce cas, il permet une conversion implicite du type de paramètre au type d'objet. Ici, cela signifierait que vous pourriez utiliser un 'int' où un' X11Painter' est attendu et le constructeur serait appelé pour faire la conversion. La déclaration du constructeur 'explicit' empêche cette conversion de type implicite. – JaakkoK

1

Cela me semble que la corruption de la pile, résultant très probablement par les

 Window     window; 
     XSetWindowAttributes winattr; 

membres, comme les autres sont tous les types primitifs. Par exemple, j'ai remarqué ceci:

XStoreName(this->display, this->window, "LaserFinger"); 

Si la fenêtre et l'affichage ne sont pas la bonne quantité de mémoire, cela pourrait aller Kaboom. Cependant, sans connaître les bibliothèques X11, je ne peux pas être beaucoup plus utile.

+0

Ceci est réellement correct. Ces fonctions sont destinées à être utilisées de cette manière. La fenêtre est à la fin un long non signé et l'affichage est une struct. Mais merci de l'avoir signalé. – Atmocreations