Je suis en phase de test d'une classe qui a pour fonction de gerer la main loop d'une application lorsque j'appelle la fonction run(). Cette fonction run appelle des fonctions virtuelles de la classe Application, mais je tombe sur un segfault que je n'arrive pas a m'expliquer. Voila le code :
Engine.hpp :
#ifndef ENGINE__HPP_
#define ENGINE__HPP_
#include "Application.hpp"
class Engine
{
public:
void run (Application * app);
};
#endif
Engine.cpp :
#include "Engine.hpp"
#include <chrono>
double now () // return the current date in seconds
{
using namespace std::chrono;
return duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
}
void Engine::run (Application * app)
{
double t = 0.0;
app->setup();
double currenttime = now();
double accumulator = 0.0;
while (app->running())
{
double newtime = now();
double frametime = newtime - currenttime;
if (frametime > 0.25) frametime = 0.25;
currenttime = newtime;
accumulator += frametime;
while (accumulator >= app->dt())
{
float dt = app->dt();
app->input(); // L'APPEL PROVOQUE UN SEGFAULT
app->update(t, dt);
t += dt;
accumulator -= dt;
}
const double alpha = accumulator / app->dt();
app->render (alpha);
}
app->cleanup();
}
Déjà, chaque tentative de déréférencement d'un pointeur doit ad minima être précédée d'une assertion (assert(ptr && "null pointer detected");, par exemple)
Ensuite, si tu essayais de transmettre ton application sous forme de référence au lieu de la transmettre sous forme de pointeur, tu pourrais sans doute t'éviter bien des soucis.
C'est d'autant plus vrai que tu connais, de toute évidence, le type de ton application dans ta fonction main(test, dans le cas présent). Tu n'as donc aucune raison de recourir à l'allocation dynamique pour app; un code proche de
int main(){
test app{/* paramètres éventuels */};
engine.run(app);
}
faisant tout aussi bien l'affaire (une fois que ton application sera transmise par référence, s'entend)
Quant à ton problème particulier, il faudra aller voir plus en profondeur, mais je ne serais pas étonné qu'il y ait un delete app qui traine quelque part
Enfin, tu devrais avoir recours à ==>la déclaration anticipée<== pour que ta classe engine connaisse la classe application
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Salut et merci @koala1 , effectivement passer ma structure par reference plutôt que par pointeur a eliminé le probleme ! (au passage je ne savais pas qu'on pouvait passer une reference sur une classe abstraite, donc merci de m'apprendre ca) Il n'y a pas vraiment besoin de déclaration anticipé puisqu'il n'y a pas de reference a Engine dans Application, du coup il n'y a pas de probleme de dépendance "croisé" entre les deux classes
Le fait de passer la structure par référence permet d'avoir un code plus robuste et plus cohérent; et de corriger le défaut de ton code qui "oubliait" de libérer l'Application. En l'occurrence cela n'a rien à voir avec le segfault. N'as-tu pas modifié autre chose par la même occasion?
@Dalfab, non je n'ai rien modifié d'autre, a part les appels de fonction (passer de app->update() a app.update()) mais moi aussi je m'interroge sur le segfault : effectivement j'ai oublié de liberer l'espace mémoire a la fin du programme, mais a ce moment là il aurait du fonctionner puis me signaler le segfault lors de la sortie de main, non ?
Ce qui me parait le plus bizarre c'est que l'application marchait sous GDB, mais pas sans GDB, et que GDB ne me signale aucun problème
segfault lors d'appel de fonction virtuelle
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
En recherche d'emploi.