最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - sf::music prevents my program from crashing? - Stack Overflow

programmeradmin0浏览0评论

Here's the program i'm asking help for:

main program

#include "fonctions.h"

int main(){
    sf::Music musique;
    musique.openFromFile("audio/musique/song.mp3");
    musique.play();
    musique.setLoop(1);

    SetConsoleOutputCP(65001);
    utilisatoireInput();

    while(1){
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::X)){
            utilisatoireInput();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && !(position%ligne==0)){
            anciennePosition = position;
            position--;
            actuafficher();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && (position%ligne !=ligne-1) && (position != planLongueur - 1)){
            anciennePosition = position;
            position++;
            actuafficher();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && position > ligne - 1){
            anciennePosition = position;
            position -= ligne;
            actuafficher();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && position < planLongueur - ligne){
            anciennePosition = position;
            position += ligne;
            actuafficher();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
            musique.setLoop(0);
            musique.stop();
            musique.openFromFile("audio/sfx/oof.mp3");
            musique.play();
        }
        if(musique.getStatus() == sf::SoundSource::Status::Stopped)
            break;
    }
    return 0;
}

header file

#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <vector>
#include <windows.h>

std::vector <char> plan{'a','b','c','d','e'};               //filling this with random variables because it crashes no matter what otherwise

unsigned int planLongueur;                                  //plane length.
unsigned int ligne;                                         //line length if l=L
unsigned int position;                                      //location on the plane (centered)
unsigned int anciennePosition;                              //previous position.

void init(){                                                //initialize plan by plane length
    for(int i = 0; i < planLongueur; i++)
        plan[i] = '.';

        plan[position] = '@';
}  
void afficher(){                                            //update display.
    system("cls");
    for(int i = 0; i < planLongueur; i++){
        std::cout << plan[i];
        if(i%ligne == ligne - 1){
            std::cout <<"\n";
        }
    }
    std::cout << "\n" << "position: "<< position 
              << "\nAppuyez sur X pour changer la longueur."
              << "\nAppuyez sur Echap pour quitter le programme."; 
}
void actualiser(){                                          //update position.
    plan[position] = '@';
    plan[anciennePosition] = '.';
}
void actuafficher(){                                        //update then display
    actualiser();
    afficher();
}

void utilisatoireInput(){
    system("cls");
    std::cout << "ENTREZ UNE PUTAIN DE LONGUEUR DE MERDE MAIS BORDEL (pair de préférence svp mais qui suis-je pour vous obliger enfin bref vous avez bien compris...): ";   
    std::cin >> planLongueur;
    ligne = static_cast<unsigned int>(sqrt(planLongueur));
    position = static_cast<unsigned int>(planLongueur/2-ligne/2);

    init();
    actuafficher();
}

What this does is that it basically creates a (as much as possible) square plane on which you can move your @ pointer using real-time input handling thanks to SFML. you can also change the "length" of the plan by pressing x and you'll be prompted to enter a new one, and you can press esc to exit the main while 1 loop which will lead to the termination of the program.

Example real situation:

......
......
......
......
...@..
......
......

position: 27
press X to change length.
press esc to leave the program.

As you may have noticed, this plane is only a bunch of dot units, which are all contained inside of a single std::vector. I was using a mere array before i decided to make this program dynamic and I also thought it would make good practice. Now we're coming to the problem(s);

1 (the not-so problem): Using a vector would make the program crash while the array wouldn't. However, I couldn't just prompt the user for input of the constant array length due, among others, to scope reasons. I don't know if that's good reasoning, but that's the idea i had at the moment.

However, I was able to fix this issue by initializing a made up value to my vector. So yeah, pretty weird. didn't notice anything like that in the documentation. I might not have paid attention though.

2 (the real problem): I wanted to test the protability of my program, so I removed everything SFML audio related, since, as you guys may know, OpenAL's licence doesn't allow you to link the audio part of SFML statically since it depends from it.

Surprise: the crashes came back at prompting ! To be precise, here's the same error I've been getting in every scenario, even those I haven't mentionned yet:

mingw32-make: *** [makefile:13: exe] Error -1073741819

btw here's the makefile (bouge.cpp being the main function file):

all: compile link clean exe

compile:
    g++ -Isrc/include -c trucs/bouge.cpp -DSFML_STATIC

link:
    g++ *.o -o bouge -Lsrc/lib -lsfml-graphics-s -lsfml-window-s -lopengl32 -lgdi32 -lsfml-audio-s -lsfml-system-s -lopenal32 -lflac -lvorbisenc -lvorbisfile -lvorbis -logg -lwinmm -lfreetype

clean:
    del *.o -R

exe:
    ./bouge.exe

so first, I tried putting the music back and removed the exit music part at the end, leaving myself only with:

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
            
            break;
    }
    return 0;
}

instead of

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
            musique.setLoop(0);
            musique.stop();
            musique.openFromFile("audio/sfx/oof.mp3");
            musique.play();
        }
        if(musique.getStatus() == sf::SoundSource::Status::Stopped)
            break;
    }
    return 0;
}

It worked fine. Then, I started removing some of the music statements at the top going from:

int main(){
    sf::Music musique;
    musique.openFromFile("audio/musique/kaos.mp3");
    musique.play();
    musique.setLoop(1);

    //rest of the program

to only:

int main(){
    sf::Music musique;
    
    //rest of the program

It still worked. And it was only when I finally removed that single line of sf::music object declaration that it started crashing at the prompting as before. How does this cause my whole vector setup to not crash?

Here's the program i'm asking help for:

main program

#include "fonctions.h"

int main(){
    sf::Music musique;
    musique.openFromFile("audio/musique/song.mp3");
    musique.play();
    musique.setLoop(1);

    SetConsoleOutputCP(65001);
    utilisatoireInput();

    while(1){
        if(sf::Keyboard::isKeyPressed(sf::Keyboard::X)){
            utilisatoireInput();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) && !(position%ligne==0)){
            anciennePosition = position;
            position--;
            actuafficher();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right) && (position%ligne !=ligne-1) && (position != planLongueur - 1)){
            anciennePosition = position;
            position++;
            actuafficher();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) && position > ligne - 1){
            anciennePosition = position;
            position -= ligne;
            actuafficher();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) && position < planLongueur - ligne){
            anciennePosition = position;
            position += ligne;
            actuafficher();
        }

        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
            musique.setLoop(0);
            musique.stop();
            musique.openFromFile("audio/sfx/oof.mp3");
            musique.play();
        }
        if(musique.getStatus() == sf::SoundSource::Status::Stopped)
            break;
    }
    return 0;
}

header file

#pragma once

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <vector>
#include <windows.h>

std::vector <char> plan{'a','b','c','d','e'};               //filling this with random variables because it crashes no matter what otherwise

unsigned int planLongueur;                                  //plane length.
unsigned int ligne;                                         //line length if l=L
unsigned int position;                                      //location on the plane (centered)
unsigned int anciennePosition;                              //previous position.

void init(){                                                //initialize plan by plane length
    for(int i = 0; i < planLongueur; i++)
        plan[i] = '.';

        plan[position] = '@';
}  
void afficher(){                                            //update display.
    system("cls");
    for(int i = 0; i < planLongueur; i++){
        std::cout << plan[i];
        if(i%ligne == ligne - 1){
            std::cout <<"\n";
        }
    }
    std::cout << "\n" << "position: "<< position 
              << "\nAppuyez sur X pour changer la longueur."
              << "\nAppuyez sur Echap pour quitter le programme."; 
}
void actualiser(){                                          //update position.
    plan[position] = '@';
    plan[anciennePosition] = '.';
}
void actuafficher(){                                        //update then display
    actualiser();
    afficher();
}

void utilisatoireInput(){
    system("cls");
    std::cout << "ENTREZ UNE PUTAIN DE LONGUEUR DE MERDE MAIS BORDEL (pair de préférence svp mais qui suis-je pour vous obliger enfin bref vous avez bien compris...): ";   
    std::cin >> planLongueur;
    ligne = static_cast<unsigned int>(sqrt(planLongueur));
    position = static_cast<unsigned int>(planLongueur/2-ligne/2);

    init();
    actuafficher();
}

What this does is that it basically creates a (as much as possible) square plane on which you can move your @ pointer using real-time input handling thanks to SFML. you can also change the "length" of the plan by pressing x and you'll be prompted to enter a new one, and you can press esc to exit the main while 1 loop which will lead to the termination of the program.

Example real situation:

......
......
......
......
...@..
......
......

position: 27
press X to change length.
press esc to leave the program.

As you may have noticed, this plane is only a bunch of dot units, which are all contained inside of a single std::vector. I was using a mere array before i decided to make this program dynamic and I also thought it would make good practice. Now we're coming to the problem(s);

1 (the not-so problem): Using a vector would make the program crash while the array wouldn't. However, I couldn't just prompt the user for input of the constant array length due, among others, to scope reasons. I don't know if that's good reasoning, but that's the idea i had at the moment.

However, I was able to fix this issue by initializing a made up value to my vector. So yeah, pretty weird. didn't notice anything like that in the documentation. I might not have paid attention though.

2 (the real problem): I wanted to test the protability of my program, so I removed everything SFML audio related, since, as you guys may know, OpenAL's licence doesn't allow you to link the audio part of SFML statically since it depends from it.

Surprise: the crashes came back at prompting ! To be precise, here's the same error I've been getting in every scenario, even those I haven't mentionned yet:

mingw32-make: *** [makefile:13: exe] Error -1073741819

btw here's the makefile (bouge.cpp being the main function file):

all: compile link clean exe

compile:
    g++ -Isrc/include -c trucs/bouge.cpp -DSFML_STATIC

link:
    g++ *.o -o bouge -Lsrc/lib -lsfml-graphics-s -lsfml-window-s -lopengl32 -lgdi32 -lsfml-audio-s -lsfml-system-s -lopenal32 -lflac -lvorbisenc -lvorbisfile -lvorbis -logg -lwinmm -lfreetype

clean:
    del *.o -R

exe:
    ./bouge.exe

so first, I tried putting the music back and removed the exit music part at the end, leaving myself only with:

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
            
            break;
    }
    return 0;
}

instead of

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)){
            musique.setLoop(0);
            musique.stop();
            musique.openFromFile("audio/sfx/oof.mp3");
            musique.play();
        }
        if(musique.getStatus() == sf::SoundSource::Status::Stopped)
            break;
    }
    return 0;
}

It worked fine. Then, I started removing some of the music statements at the top going from:

int main(){
    sf::Music musique;
    musique.openFromFile("audio/musique/kaos.mp3");
    musique.play();
    musique.setLoop(1);

    //rest of the program

to only:

int main(){
    sf::Music musique;
    
    //rest of the program

It still worked. And it was only when I finally removed that single line of sf::music object declaration that it started crashing at the prompting as before. How does this cause my whole vector setup to not crash?

Share Improve this question edited Feb 7 at 14:26 genpfault 52.1k12 gold badges91 silver badges148 bronze badges asked Feb 6 at 11:42 RMBRMB 11 bronze badge New contributor RMB is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 3
  • Please try to create a minimal reproducible example of the program that crashes, with emphasis on the minimal part. Then use a debugger to catch the crash and see when and where in your program it happens, and examine all involved variables and their values to make sure it all seems valid. – Some programmer dude Commented Feb 6 at 11:46
  • On a different note, what resources are you using to learn C++? Using header-files to split the project into multiple files is not really a good way to do it. Especially since you seem to know about make. Or are you just copying from some web-site without knowing exactly what make is and does, or how a Makefile works? Then it's likely that you have the same problem with your code, and you're part of a cargo cult. If so I suggest you find some better learning material to learn the basics from the ground up, before starting with SFML. – Some programmer dude Commented Feb 6 at 11:49
  • Any change to planLongueur should be accompanied by a call that mutates the size of plan, such as plan.resize(planLongueuer). Otherwise you are writing off the end of the memory pointed to by plan... – Botje Commented Feb 6 at 13:15
Add a comment  | 

1 Answer 1

Reset to default 1
for(int i = 0; i < planLongueur; i++)
    plan[i] = '.';

You're assigning to plan[i], but you never resized plan to actually have planLongueur elements. So you're assigning into memory you don't own. That's why your program crashes at random. sf::Music probably fixes it by changing the pattern of heap traffic so that you end up writing into memory that sf::Music owns (producing unpredictable but non-crashing results), instead of into completely unallocated memory (producing a segfault).

Change the line above to:

plan.resize(planLongueur, '.');

and you'll have fixed at least that one bug. (There may be more bugs.)

发布评论

评论列表(0)

  1. 暂无评论