Archives mensuelles pour juillet 2008

Utiliser gprof avec CodeBlocks 8.02

Gprof est un formidable outil de profiling qui vous permet de savoir quelles partie de votre code s’exécutent le plus souvent,prennent le plus de temps etc…

Son utilisation est facilitée sous windows grâce au plugin de CodeBlocks « Code Profiler ».Pour l’utiliser vous devez compiler votre projet avec l’option « -pg ». Une fois celui-ci compilé, vous devez le lancer sur la durée convenable pour avoir résultats significatifs ( Enregistrer le programme tourner à vide n’apportera rien ).Ensuite il suffit de consulter les données recueillies en cliquant sur « Plugins>Code Profiler ».

Maintenant il y a un problème avec CodeBlocks 8.02 . Les données sont nulles partout. Pour y remédier,il faut suivre les consignes données sur le forum de codeblocks : à savoir télécharger une version plus ancienne mais stable de binutils puis de la décompresser dans le dossier MingW. Faîtes une sauvegarde de votre dossier au cas où mais chez moi il n’y a eu aucun problème ( si jamais le téléchargement ne marche pas, essayez avec un autre miroir ).

std::vector : Passer de l’itérateur à l’indice et vice-versa

Le container std::vector a ceci de particulier que tous ses éléments sont placés dans des zones mémoires contigües. C’est donc le container à privilégier dès lors qu’on a besoin de parcourir un ensemble d’éléments rapidement. Un effet pervers de cette rapidité et que la suppression ou l’ajout d’un élément oblige parfois à réallouer tout le vector ( il faut en effet disposer d’une quantité de mémoire suffisante et contigüe ).Il existe divers moyens pour contrecarrer ces effets ( cf ici : à savoir utiliser la fonction membre .reserve() et l’utilisation d’un double buffer ).

Après cette brève introduction, venons en au sujet,on suppose l’existence de std::vector<int> v :

  • Passer de l’indice à l’itérateur : On veut avoir un itérateur sur le 4ième élément de notre vector.Il suffit de faire: std::vector<int>::iterator = v.begin() + 4; On peut également utiliser std::advance comme décrit sur ce site de référence .
  • Plus rare maintenant, le passage d’un itérateur à l’indice. Il faut utiliser la fonction std::distance . Il existe 2 prototypes de cette fonction mais seule la plus récente est à utiliser ( la première étant dépréciée car buggée etc… ).Je donne la fonction que j’utilise telle qu’elle :
    void CRunner::Kill(IBullet* bullet){
    std::vector&lt;
    IBullet*&gt;::iterator it = std::find(mBullets.begin(),mBullets.end(),bullet);
    
    std::vector&lt;int&gt;::difference_type id = std::distance(mBullets.begin(),it);
    mFreeBullets[mStoreIndex].push_back(id);
    }
    

J’espère que cela vous aura aidé.

Nb: Différence intéressante, l’utilisation d’at() est équivalente à celle de l’opérateur [] à ceci près qu’elle lève une exception si jamais on se place hors du tableau. Par exemple: 

v.push_back(3);// on insere l'element '3' qui a pour indice 0
v[1];// provoque une segmentation fault bof bof pour l'image donnée à l'utilisateur
v.at(1); // lancera une exception qu'on peut attraper et l'utilisateur sait au moins qu'on a pensé à prendre en compte cette erreur

Nb2: Voir la FAQ C++ de developpez.com pour savoir comment choisir le container approprié.