CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C++/SDL]Programme qui plante...

PanPanBoom
PanPanBoom
Niveau 10
26 février 2015 à 17:20:08

Bonjour/Bonsoir tout le monde !

Voici mon problème : Je code un programme qui compare des images afin de trouver la correspondante dans la base de données. Seulement, après que l'utilisateur entre le chemin de l'image à comparer, le programme cesse de fonctionner, je ne sais pas pourquoi. Voici mes fichiers :

main.cpp : http://pastebin.com/h8KcPVwf
rechercheDicho.cpp : http://pastebin.com/SXtkydRz
obtenirPixel.cpp : http://pastebin.com/dnyZXy10
input.cpp : http://pastebin.com/TjrLfTpS
output.cpp : http://pastebin.com/k8nGi69n

J'comprends vraiment pas d'où ça vient, quelqu'un pour éclairer ma lanterne s'il vous plait ? Merci d'avance !

-Nath-X
-Nath-X
Niveau 10
26 février 2015 à 19:42:15

Tu serais pas en train d'essayer d’accéder aux pixels de surfaces inexistantes ?
Parce que même si ton tableau de SDL_Surface* fait 88 cases, il n'y en a que 7 d'initialisées. Ce qui fait que lorsque tu lances la rechercheDico(), tu appelle la fonction obtenirPixel() sur des SDL_Surface* non définie.
Sinon n'oublies pas de libérer les SDL_Surface* à la fin du programme, sinon il a fuite de mémoire.

Ah et aussi, dans main(), tu peux faire directement:

val = SDL_LoadBMP(cheminVal.c_str());
bugar
bugar
Niveau 48
26 février 2015 à 19:44:52

J'ai pas test et j'ai un peux regardé le code alors je te donne des pistes a vérifier:

  • Il se peux que la chaine de caractere qui represente ton chemin face plus de 100 caracteres. Si chemin > 100 -> pas assez d'espace de stockage -> segmentation fault -> programme qui plante.
  • Test le retour de la fonction SDL_LoadBMP().

Si NULL c'est que le chemin est mauvais ou erreur de la fonction sdl pour x ou y raison. Du coup dans la fonction suivante il vas lire dans val: NULL et ca prend une seule case mémoire. Or dans "dichotomie", tu cherche à accèder a des valeurs dont tu aura pas le droit -> segmentation fault -> programme plante

  • Dans dichotomie ta premiere boucle vas parcourir les 88 cases, hors tu en a initialisé que 8 sur les 88 avec des images les 80 autres cases sont probablement a NULL , donc a la 9eme la sdl_surface est pas initialisé corectement -> erreur dans obtenirpixel car il vas chercher des pixels(i,j) la ou il y en a pas-> erreur de segmentation -> programme qui plante
  • Dans cette même fonction tu fait un parcours sur i et j , leur valeur etant fixe, si ton image référence ( celle ds tab[88] ou val) est plus petite que 508 *480 -> erreur de segmentation -> programme qui plante

N'oublie pas de :

  1. Initialiser tes pointeurs
  2. Tester tes pointeurs
PanPanBoom
PanPanBoom
Niveau 10
26 février 2015 à 19:46:50

Bh justement nan sachant que quand j'entre un chemin dans la console, je fais en sorte que ce soit un déjà initialisé.
Merci quand même !

PanPanBoom
PanPanBoom
Niveau 10
12 mars 2015 à 01:38:03

Merci déjà pour vos réponse mais j'ai le même problème pour un autre projet, ça fait depuis le début d'après-midi que je cherche, sans succès. J'arrive pas à comprendre, en gros dès que j'appelle la fonction bataille, le programme plante. Voici mes fonctions :

Bataille.cpp : http://pastebin.com/PwzUeVNj

Merci d'avance ! :-)

Lagrangien
Lagrangien
Niveau 8
12 mars 2015 à 11:01:06

Mais est-ce qu'il plante à l'appel de creerCarte ? (dans Bataille.cpp)

PanPanBoom
PanPanBoom
Niveau 10
12 mars 2015 à 11:44:12

Alors j'ai enlever l'appel à cette fonction mais ça plante encore.. :-(

godrik
godrik
Niveau 30
12 mars 2015 à 15:55:43

Ca veut dire quoi concretement "le programme cesse de fonctionner," ?

PanPanBoom
PanPanBoom
Niveau 10
12 mars 2015 à 21:58:09

Bh... Qu'il a planté ? ^^

89ron
89ron
Niveau 10
13 mars 2015 à 15:50:02

Tu as bien initialiser la bibliothèque avant d'utiliser SDL_LoadBMP ?

Sinon tu doits initialiser ta libraire ainsi :

 
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
     // fprint est utiliser uniquement a la place de std::cout afin de pouvoir 
     // lire correctement  le message d'erreur retourner par SDL_GetError()
     // fprintf provient de #include <cstdio>
     std::fprintf(stdout, "SDL Initialisation failed - %s \n", SDL_GetError());  
}
godrik
godrik
Niveau 30
13 mars 2015 à 16:15:52

Le fait qu'une application plante, ca peut etre un million de chose. Est ce que c'est une division par zero, une erreur de segmentation, stack overflow, out of memory, un appel a exit?

En general, faire passer l'application dans valgrind aide. Mais peut etre que valgrind et la sdl ne vont pas tres bien ensemble.

PanPanBoom
PanPanBoom
Niveau 10
13 mars 2015 à 16:41:58

Le 13 mars 2015 à 15:50:02 89ron a écrit :
Tu as bien initialiser la bibliothèque avant d'utiliser SDL_LoadBMP ?

Sinon tu doits initialiser ta libraire ainsi :

 
if (SDL_Init(SDL_INIT_EVERYTHING) < 0)
{
     // fprint est utiliser uniquement a la place de std::cout afin de pouvoir 
     // lire correctement  le message d'erreur retourner par SDL_GetError()
     // fprintf provient de #include <cstdio>
     std::fprintf(stdout, "SDL Initialisation failed - %s \n", SDL_GetError());  
}

Oui, sinon j'aurais directement une erreur, là la fenêtre s'ouvre et fait d'autres trucs mais dès que je vais dans cette fonction le programme plante.

godrik :d) Bh il me semble qu'il n'y a rien de tous ça justement. :(

89ron
89ron
Niveau 10
13 mars 2015 à 16:57:39

Dans ce cas test si ta fonction renvoi un pointeur NULL

ex :


if( SDL_LoadBMP("BDD/empreinte_001.bmp") == NULL )
{
  std::fprintf(stdout, "SDL_LoadBMP - %s \n", SDL_GetError());
}
else 
{
  std::fprintf(stdout, "SDL_LoadBMP est OK \n");
}

SDL_GetError te donnera surement ton problème problème.

PanPanBoom
PanPanBoom
Niveau 10
23 mars 2015 à 20:46:22

Arf, ce problème là est passé, regarde quelques postes au dessus. :p)

89ron
89ron
Niveau 10
23 mars 2015 à 23:01:14

Je te conseille d’exécuter ton jeu dans Visual Studio Express en mode Depug (pas Release), il pointera automatiquement sur la ligne qui pose problème.

Parce-que là il manque pas mal de fichier pour t'aider.

PS: Tu utilises quel tuto pour la SDL ?

Message édité le 23 mars 2015 à 23:05:24 par 89ron
PanPanBoom
PanPanBoom
Niveau 10
23 mars 2015 à 23:18:48

Bh j'utilise déjà un Debugger mais ça me signale rien. :-( J'utilise plus de tutos,mais avant j'utilisais le tuto du siteduzero (OpenClassrooms maintenant.).

EDIT: Au cas où, mon IDE est Code::Blocks avec en compilateur mingw.

Message édité le 23 mars 2015 à 23:19:28 par PanPanBoom
PanPanBoom
PanPanBoom
Niveau 10
25 mars 2015 à 23:24:32

Bon, j'ai reprogrammé tout le fichier (mis à part la fonction distribuerCarte, voici ce que ça donne :

#include <SDL/SDL.h>

#include "bataille.h"
#include "Boss.h"
#include "data.h"
#include "rand_a_b.h"
#include "Barbare.h"
#include "Magicien.h"
#include "Sorcier.h"
#include "Druide.h"
#include "Debutant.h"

void bataille(SDL_Surface* ecran)
{
    SDL_Surface *fond(SDL_LoadBMP("GRAPHISMES/BATAILLE/champ.bmp"));
    SDL_Rect pos;
    SDL_Event event;
    int nbBarbare(getBarbare()), nbMagicien(getMagicien()), nbSorcier(getSorcier()), nbDruide(getDruide()), nbDebutant(getDebutant());
    int nbCartes(nbBarbare+nbMagicien+nbSorcier+nbDruide+nbDebutant);
    int deckJ1[nbCartes], deckIA[nbCartes], i(0);
    bool continuer(true);
    Boss j1(500, SDL_LoadBMP("GRAPHISMES/CARTES/BOSS/boss.bmp")), ia(500, SDL_LoadBMP("GRAPHISMES/CARTES/BOSS/boss2.bmp"));
    Carte cJ1[nbCartes], cIA[nbCartes];

    pos.x = 0;
    pos.y = 0;

    for(i = 0; i < nbCartes; i++)
        deckJ1[i] = distribuerCarte(nbBarbare, nbMagicien, nbSorcier, nbDruide, nbDebutant);

    /*  ***** PLANTE *****
    
    for(i = 0; i < nbCartes; i++)
        cJ1[i] = creerCarte(deckJ1, i);
        
        ***** PLANTE ***** */

    while(continuer)
    {
        SDL_PollEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                exit(EXIT_SUCCESS);
                break;

            case SDL_KEYDOWN:
                if(event.key.keysym.sym == SDLK_ESCAPE)
                    continuer = false;

                break;
        }

        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
        SDL_BlitSurface(fond, NULL, ecran, &pos);
        j1.afficher(ecran, 559, 396);
        ia.afficher(ecran, 559, 205);
        SDL_Flip(ecran);
    }
}

int distribuerCarte(int nbBarbare, int nbMagicien, int nbSorcier, int nbDruide, int nbDebutant)
{
    int carte;

    while(!carte)
    {
        carte = rand_a_b(1, 5);

        if(!nbBarbare)
        {
            if(carte == 1)
                carte--;
        }

        if(!nbMagicien)
        {
            if(carte == 2)
                carte = 0;
        }

        if(!nbSorcier)
        {
            if(carte == 3)
                carte = 0;
        }

        if(!nbDruide)
        {
            if(carte == 4)
                carte = 0;
        }

        if(!nbDebutant)
        {
            if(carte == 5)
                carte = 0;
        }
    }
    return carte;
}

Carte creerCarte(int deck[], int x)
{
    Barbare barbare;
    Magicien magicien;
    Sorcier sorcier;
    Druide druide;
    Debutant debutant;

    switch(deck[x])
    {
        case 1:
            return barbare;
            break;

        case 2:
            return magicien;
            break;

        case 3:
            return sorcier;
            break;

        case 4:
            return druide;
            break;

        case 5:
            return debutant;
            break;
    }
}

Comme vous avez pu le voir, j'ai remarquer où ça plante : à l'appel de la fonction creerCarte, mais bon, je vois toujours pas pourquoi. :(

89ron
89ron
Niveau 10
26 mars 2015 à 00:24:18

Peux-tu nous détailler ta Class Carte ?

Sinon ton switch dans la methode creeCarte est mauvais. (faut éviter de mettre plusieurs return, c'est chiant a debug, une fonction / une methode = une sortie.)

Les class Barbare, Magicien, Sorcier, Druide et Debutant sont elle des class dérivée de Carte ? Parceque ta fonction creeCarte s'attend a retourner des objets Cartes et non des objets Barbares, etc.

Ta méthode distribuerCarte a une variable non initialise : int carte; du coup ton while (!carte) est initialiser avec une valeur aléatoire très grandes,

PS: Sinon je voudrais pas te décourager mais évite Openclassroom a l'avenir car ton code dans l'ensemble ressemble plus a du "C with Class" que du vrai C++.

PanPanBoom
PanPanBoom
Niveau 10
26 mars 2015 à 11:50:38

Carte.h :

#include <iostream>

#include "Boss.h"

class Carte
{
    public:
        Carte();
        Carte(int vie, int level, int attaque, int defense, SDL_Surface *image);
        void attaquer(Carte &cible);
        void attaquerBoss(Boss &cible);
        void recevoirDegats(int degats);
        void initPos(int x, int y);
        void deplacer();
        void afficher(SDL_Surface* ecran, int x, int y);
        SDL_Surface *getImage();
        SDL_Rect &getPos();

    protected:
        int m_vie;
        int m_attaque;
        int m_defense;
        int m_level;
        int m_x;
        int m_y;
        std::string m_race;
        SDL_Surface *m_image;
        SDL_Rect m_pos;
};

#endif // CARTE_H_INCLUDED

Carte.cpp :

#include <SDL/SDL.h>

#include "Carte.h"

using namespace std;

Carte::Carte()
{

}

Carte::Carte(int vie, int level, int attaque, int defense, SDL_Surface *image) : m_vie(vie), m_level(level), m_attaque(attaque), m_defense(defense), m_image(image)
{

}

void Carte::attaquer(Carte &cible)
{
    cible.recevoirDegats((1 - m_defense / 100) * m_attaque);
}

void attaquerBoss(Boss &cible)
{
    cible.recevoirDegats(1);
}

void Carte::recevoirDegats(int degats)
{
    m_vie -= degats;

    if(m_vie < 100)
        m_vie = 0;
}

void Carte::initPos(int x, int y)
{
    m_pos.x = x;
    m_pos.y = y;
}

void Carte::deplacer()
{
    // A FAIRE
}

void Carte::afficher(SDL_Surface* ecran, int x, int y)
{
    initPos(x, y);
    SDL_BlitSurface(m_image, NULL, ecran, &m_pos);
}

SDL_Surface *Carte::getImage()
{
    SDL_SetColorKey(m_image, SDL_SRCCOLORKEY, SDL_MapRGB(m_image->format, 255, 255, 0));
    return m_image;
}

SDL_Rect &Carte::getPos()
{
    return m_pos;
}

Comment ça mauvais ? Il vaut mieux que je mette une tonne de if ?

Oui, elles sont héritées de la classe Carte !

Oui, mais après elle est initialisée avec la fonction rand_a_b.

Qu'entends-tu par C with class ?

89ron
89ron
Niveau 10
26 mars 2015 à 14:53:38

Comment ça mauvais ? Il vaut mieux que je mette une tonne de if ?

non essai plutôt ça :



   Carte carte;

    switch(deck[x])
   {
        case 1:
            carte = static_cast<carte>(barbare);
            break;

        case 2:
            carte = static_cast<carte>(magicien);
            break;

        // etc.

  }
  return carte;
}

Oui, elles sont héritées de la classe Carte !

Oui, mais après elle est initialisée avec la fonction rand_a_b.

Qu'entends-tu par C with class ?

- Une procédure Bataille qui appelle un header bataille -> c'est du C
- Initialiser des variables avant l’exécution de multiples procédure dans une boucle principale c'est du C.
- Utiliser des Classes avec des méthodes uniquement public, -> c'est du C with Class.
- Utiliser des tabeaux [ ] -> c'est du C
- Utiliser des int pour délimiter des la taille du tableaux -> c'est du C.

Dans ton main initialiser des tableaux de cette manière, est suicidaire :

    

SDL_Surface *tab[88] = 
{SDL_LoadBMP("BDD/empreinte_001.bmp"), SDL_LoadBMP("BDD/empreinte_002.bmp")}

 

Que fait tu si le fichier empreinte_002.bmp est pas trouver par SDL_LoadBMP ? Tu verifies pas s'il y a une erreur, du coup SDL_LoadBMP peux retourner un pointeur NULL qui fera planter ton application, quand le tableau sera parcouru.

Au lieu d'utiliser les tableau du C, préfère les Vectors, qu lieu d'utiliser des tableau de Class, utilise des objets, ex:

au lieu de :

 int deckJ1[nbCartes], deckIA[nbCartes];

préfère :
Deck deckJoueur ( /*nbCartes*/ 7 , /*nom du deck*/ "joueur" ); Deck deckJoueur ( /*nbCartes*/ 8 , /*nom du deck*/ "ia" );

N'utilise pas de boucle for pour remplir tes decks, c'est a ta class Deck de les remplir.
Revoi l'utilisation des pointeur ou des références, parce-que tes objet en sortie de fonctions sont retourner souvent par copie et non par référence ou par pointeur.

Tes classes doivent avoir aussi des méthodes privées.

Ton main doit être mieux organiser, il devrait plus ressembler a ceci :



#include <cstdio>
#include <SDL.h>

#include "Debug.h"
#include "Game.h"

const int width = 640;
const int height = 480;
const Uint32 fps = 60;
const Uint32 delay_time = (Uint32)(1000.f / fps);

int main(int argc, char* args[])
{
	Uint32 frameStart, frameTime;
	int error = 0;

	std::cout << "game init attempt...\n";

	//Initialisation du jeu et de la SDL
	//doit se faire dans une classe Game
	if (TheGame::Instance()->init("game1", width, height))
	{
		frameStart = SDL_GetTicks();

		// Main loop
		while (TheGame::Instance()->running())
		{
			// Recuperation des evenements Claviers/Mannette/Souris
			TheGame::Instance()->handleEvents();

			// Mise a jour des Objets
			TheGame::Instance()->update();

			// Affichage des objets
			TheGame::Instance()->render();

			// Verification des images par secondes

			frameTime = SDL_GetTicks() - frameStart;

            if (frameTime < delay_time)
			{
				// Permet de soulager le processeur
                SDL_Delay(delay_time - frameTime);
			}
		}
	}
	else
	{
        std::fprintf(stdout, "Game init failure - %s \n", SDL_GetError());
		error = -1;
	}

	// SDL quit
	std::cout << "game closing... \n";

	// Netoie la memoire des differentes allocation dynamiques
	TheGame::Instance()->clean();

	PAUSE; // system("pause");

	return error;
}

Message édité le 26 mars 2015 à 14:57:44 par 89ron
Sous forums
  • Aide à l'achat Mac
  • Création de sites web
  • Création de Jeux
  • Linux
  • Programmation
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment