First time posting here, so sorry if this is a beginner's problem. I am trying to create a Snake class for a simple game I'm making but the debugger keeps throwing weird exceptions.
Every time I debug the program, it takes me into a 'vector' file, points me to a certain line and says: "read access violation.'this' was nullptr". When I run it without debugging it just terminates with the message: "exited with code -1073741819.".
I've been trying to solve this for hours but still have no idea what the problem is. Is there something wrong with my code, or does the problem not lie there? Thanks in advance!
In Snake.h:
#include <vector>
class Snake{
private:
std::vector<sf::RectangleShape> body;
int speed;
public:
Snake();
void draw_body(sf::RenderWindow& windowRef);
void move(sf::RenderWindow& windowRef);
void set_speed(int s);
};
In Snake.cpp: (I haven't finished Snake::move() yet)
#include "Snake.h"
#include <SFML\Graphics.hpp>
Snake::Snake() : speed{ 10 }, body{ sf::RectangleShape { sf::Vector2f(50.f,50.f) } }{
body.at(0).setPosition(50.f, 50.f);
}
void Snake::draw_body(sf::RenderWindow& windowRef) {
for (sf::RectangleShape rect : body) {
windowRef.draw(rect);
}
}
void Snake::set_speed(int s) {
speed = s;
}
void Snake::move(sf::RenderWindow& windowRef) {
;
}
In main.cpp:
#include <SFML\Graphics.hpp>
#include <iostream>
#include "Snake.h"
class Snake;
int main() {
sf::RenderWindow window(sf::VideoMode(800, 800), "MY window", sf::Style::Close | sf::Style::Titlebar);
Snake* snake{};
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
}
window.clear(sf::Color::White);
snake->draw_body(window);
window.display();
}
return 0;
}
This is because your code has undefined behavior (UB). It can work by coincidence, it can fail without any symptom, or the weirdest things can happen.
The debugger takes in general extra care, adding a lot of controls. And it fortunately spotted the use of a null pointer. In fact, this line does not what you think it does:
Snake* snake{};
No Snake is created. snake is a pointer to Snake. So you've just initialized a pointer. What do you think its value is?
THe best option here is to get rid of the pointer:
Snake snake{}; // no *, so now you have a real snake object ready to use
...
snake.draw_body(window); // no -> since it's no longer a pointer
This line:
Snake* snake{};
Does not initialize an instance of the Snake class, but a pointer to an instance. Pointers are integers at the assembly level and are initialized to 0 by default, the same numeric value as NULL in C and nullptr in modern C++ (these are all identical at the assembly level).
To fix this, you either need to allocate an instance of Snake on the heap with new and delete it when you're done using it or allocate the instance on the stack by removing the pointer.
Related
We (school) are developping a game in C++ with SFML. The game is a fight game, where we need to play little sounds when the player gets hit for exemple.
I'm attempting to play a sf::Sound in a loop. I know we should not call the play() method of sf::Sound in a loop, but as the SFML apps all run in while loops, I have no other choices. Or at least, I don't know any other way to do it.
I tried to use a sound manager, I read multiple posts about it but I found nothing working.
Here is a sample code :
#include <SFML/Audio.hpp>
#include <vector>
#include <iostream>
int main() {
int FPS = 60;
// sf::Music music;
// if(!music.openFromFile("resources/audio/fight_theme.ogg")) {
// std::cout << "Music was not found" << std::endl;
// }
// music.setVolume(10.f);
// music.play();
// Create the main window
sf::VideoMode desktopMode = sf::VideoMode::getDesktopMode();
sf::RenderWindow app(
sf::VideoMode(
desktopMode.width,
desktopMode.height,
desktopMode.bitsPerPixel),
"SkyddaForStackOverflow",
sf::Style::Fullscreen
);
app.setFramerateLimit(FPS);
//Main loop
while (app.isOpen()) {
/*In the actual code, we have two player instances.
When the user press S or keyDown button, we call the attack function.
In the function, we deal the damages to the ennemy, then we call playSound
to play the hitting sound
Please note this is a sample code to help understanding the case.
In the actual code, everything is delegated to the Player class, to a SoundLoader (which is basically playSound() here)
The problem is, even with delegation, even if the playSound method is not situated in the main loop,
it is called in the main loop so the location of the code does not make any difference : it won't play since it won't
be called outside of a loop as we do for the background music (see commented code after main() {..., the background music
works fine.*/
if(player.attack(ennemy)) {
playSound();
}
}
return EXIT_SUCCESS;
}
void playSound() {
sf::SoundBuffer buffer;
if(!buffer.loadFromFile(path)) {
std::cout << "Sound was not found at " << path << std::endl;
}
sf::Sound sound(buffer);
sound.play();
}
Don't hesitate if you have additionnal questions.
Thanks !
The issue is not with "being called outside the loop"; the issue is that your sf::Sound object is destroyed at the end of the playSound function!
First, define two global (or class-) variables:
std::map<std::string, sf::SoundBuffer> buffers;
std::map<std::string, sf::Sound> sounds;
You can now define playSound as follows:
void playSound(std::string path) {
if (auto it = sounds.find(path); it == sounds.end()) {
bool ok = buffers[path].loadFromFile(path);
// do something if ok is false
sounds[path] = sf::Sound{buffers[path]};
}
sounds[path].play();
}
This will keep your sf::Sound objects (and associated sf::SoundBuffers) alive. The first call will load the file from disk, the subsequent calls will just restart the existing sound.
Note that this code is slightly suboptimal in favor of understandability: it looks up sounds[path] twice. As an exercise to you, get rid of the second lookup by reusing it in the play call.
I have a question which is quite general, but I hope someone will be able to at least point me in the right direction.
I created my project a I was building it only in Debug mode with /MDd flag.
But it started to have perfomance issues, so I wanted to try it in Release mode to see, how it goes.
Problem is, that when I use /MD or /MT flag and Release mode my application instantly crashes.
So I tried to find out why. It works fine in Debug. I've tried some code changes, but nothing helped. So I decided to make my app just start and comment out rest of my code. But it was still crashing. Even when my code was unused. It didn't crash only, when I completly removed those unused parts of code.
I think it's something with variable inicialization/declaration, but I'm not quite sure what I should look for.
Could someone suggest me what can cause application to crash even if it's just Declaration/Inicialization and is not even used in RunTime?
I hope you can somehow understand what is my problem.
Thanks for any suggestions!
EDIT: Code which crashes, when unused code is in project, but does not crash when i remove unused code.
#include "core/oxygine.h"
#include "Stage.h"
#include "DebugActor.h"
//#include "Galatex.h"
using namespace oxygine;
//called each frame
int mainloop()
{
//galatex_update();
//update our stage
//update all actors. Actor::update would be called also for all children
getStage()->update();
if (core::beginRendering())
{
Color clearColor(32, 32, 32, 255);
Rect viewport(Point(0, 0), core::getDisplaySize());
//render all actors. Actor::render would be called also for all children
getStage()->render(clearColor, viewport);
core::swapDisplayBuffers();
}
//update internal components
//all input events would be passed to Stage::instance.handleEvent
//if done is true then User requests quit from app.
bool done = core::update();
return done ? 1 : 0;
}
//it is application entry point
void run()
{
ObjectBase::__startTracingLeaks();
//initialize Oxygine's internal stuff
core::init_desc desc;
#if OXYGINE_SDL || OXYGINE_EMSCRIPTEN
//we could setup initial window size on SDL builds
desc.w = 1800;
desc.h = 1000;
//marmalade settings could be changed from emulator's menu
#endif
//galatex_preinit();
core::init(&desc);
//create Stage. Stage is a root node
Stage::instance = new Stage(true);
Point size = core::getDisplaySize();
getStage()->setSize(size);
//DebugActor is a helper actor node. It shows FPS, memory usage and other useful stuff
DebugActor::show();
//initialize this example stuff. see example.cpp
//galatex_init();
#ifdef EMSCRIPTEN
/*
if you build for Emscripten mainloop would be called automatically outside.
see emscripten_set_main_loop below
*/
return;
#endif
//here is main game loop
while (1)
{
int done = mainloop();
if (done)
break;
}
//user wants to leave application...
//lets dump all created objects into log
//all created and not freed resources would be displayed
ObjectBase::dumpCreatedObjects();
//lets cleanup everything right now and call ObjectBase::dumpObjects() again
//we need to free all allocated resources and delete all created actors
//all actors/sprites are smart pointer objects and actually you don't need it remove them by hands
//but now we want delete it by hands
//check example.cpp
//galatex_destroy();
//renderer.cleanup();
/**releases all internal components and Stage*/
core::release();
//dump list should be empty now
//we deleted everything and could be sure that there aren't any memory leaks
ObjectBase::dumpCreatedObjects();
ObjectBase::__stopTracingLeaks();
//end
}
#ifdef __S3E__
int main(int argc, char* argv[])
{
run();
return 0;
}
#endif
#ifdef OXYGINE_SDL
#include "SDL_main.h"
extern "C"
{
int main(int argc, char* argv[])
{
run();
return 0;
}
};
#endif
#ifdef EMSCRIPTEN
#include <emscripten.h>
void one() { mainloop(); }
int main(int argc, char* argv[])
{
run();
emscripten_set_main_loop(one, 0, 0);
return 0;
}
#endif
So I'll write it here for possibly other newbies like me which would find themselves in similar sutiation.
My problem was in Initialization of static and other variables which were "outside of function". For example:
MyObject object = new MyObject(); //This was the reason, why it was crashing, just had to move
// initialization of such variables to function which was called with object creation.
void MyClass::myFunction(){
object->doSomething();
}
So when program started inicialization of those variables caused crash of program.
Note: It seems like it was problem with objects, cause variables like Integers or such were just fine.
Well, I'm not totally sure why this is allowed in Debug mode, but crashes Release mode right after start, maybe someone could answer under this comment and explain this behavior, I'm just begginer and I'm doing lot of bad stuff, but I'm trying and that's good, right? :D
I hope i didn't waste too much of your time guys and maybe this post will be useful to someone in future.
I'm making a program that can update the states of objects whilst rendering.
So my first approach was the obvious draw and update in the main while loop, but this problem limited the update state part to the speed of rendering (the computer speed) so this wasn't a good approach.
So I tried to think about the problem and came up with a solution that making a detached thread whose purpose is to update the game. Here is my code of this:
//DEFAULT
#include <iostream>
#include <chrono>
#include <thread>
//SFML
#include <SFML/Graphics.hpp>
void sleep_fnc(bool*);
void update_game(bool*/*, Some objects...*/);
#define cycles_per_milisecond 1000/30
int main() {
bool flag = true;
sf::RenderWindow window(sf::VideoMode(680, 480), "I work!");
std::thread (sleep_fnc, &flag).detach();
std::thread(update_game, &flag/*, Some objects...*/).detach();
if (window.isOpen()) {
window.clear();
//DRAW STUFF HERE
window.display();
}
return 0;
}
void sleep_fnc(bool *flag_ptr) {
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(cycles_per_milisecond));
*flag_ptr = true;
}
}
void update_game(bool *flag_ptr/*, Some objects...*/) {
while (true) {
if (*flag_ptr) {
//Do update stuff
*flag_ptr = false;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
After I fiddled around with this code someone else realized that this wasn't such a good solution (thanks to you whomever pointed it out). The reason for this is if one object is being modified by the update loop WHILE the render loop is in its cycle something undefined would probably be the outcome, so I went back and started thinking again.
After thinking I came up with a solution that every class could inherit some universal class that had a boolean whether the object was being used by the draw loop or update loop, if it was in use, one of the loops would wait until the boolean flag indicated that it was ready for use again. It would probably be best if the update loop wasn't the one to wait.
Then it finally hit me that drawing the objects would be useless if they hadn't been updated. I believe that using a timer to test execution time and using that is unreliable, and there must be some other way than limiting the frame rate.
Would this prove that a frame rate higher than the update-rate is useless and is there some other approach that doesn't involve testing the execution time of last cycle and using that?
I've got a "list iterator not dereferencable" error. I've figured that this is often caused by trying to iterate too far through a list, however I can't find the cause of it. I'm staying strictly within the functions of the std::list API, so I don't know what exactly is going wrong in the below code to cause this error.
There are a few mysteries surrounding the error. The main focus of this issue is GameStateManager::HandleEvents(), during the list iteration. At the point of breaking, I have added five elements to the list, called list::remove() for each (making an empty list) and added four more elements. However, as you can see below, I print the size of the list before iterating through it. While debugging, this has shown something confusing - the size, as returned by list::size(), is different from the actual size (as viewed in the list::size variable itself, via the Visual Studio debugger). This only happens prior to the error - normally both values are the same. However, right before the error, size() returns a value unequal to the size member value of the list. It consistently contains the previous value, prior to the first elements being removed. I can't help but feel this discrepancy has something to do with the "list iterator not dereferencable" error.
Additionally confusing, the print command is not executable immediately prior to the error-triggering code. Additionally, in GameStateManager::HandleEvents(), no custom breakpoints are triggered prior to fatal for loop. Perhaps these anomalies are separate issues, however I figured they may be useful to know.
GameStateManager.h
#pragma once
#include "Tools.h"
#include "TitleScreenState.h"
#include "Game.h"
#include "Timer.h"
#include <list>
class GameState;
class EventHandler;
class GameStateManager
{
public:
GameStateManager(void);
~GameStateManager(void) { m_currentState->OnEnd(); }
void Run(void);
void Quit(void) { m_running = false; }
// Event Handler Functions
void AddHandler(EventHandler* handler) { m_eventHandlers.emplace_back(handler); }
void RemoveHandler(EventHandler* handler) { m_eventHandlers.remove(handler); }
private:
std::list<EventHandler*> m_eventHandlers; // All of the handlers who are passed the events
bool m_running; // The universal boolean for whether or not the program is running
int delta; // The time since the last frame
Timer m_FPSTimer; // The timer that keeps track of the time since the last update
GameStateID startStateID;
GameState* m_currentState; // Pointer to the current game state
// Poll and pass events to the current state
void HandleEvents(void);
};
GameStateManager.cpp
#include "GameStateManager.h"
#include "EventHandler.h"
#include "ToolKit.h"
#include "Game.h"
#include <time.h>
GameStateManager* g_manager = nullptr;
GameStateManager::GameStateManager(void)
: m_eventHandlers(), delta(0), m_running(true), startStateID(GSID_TITLE),
m_currentState(nullptr), m_titleScreen(nullptr), m_game(nullptr)
{
// Initialise time
srand(time(nullptr));
}
void GameStateManager::Run(void)
{
Initialise();
while (m_running)
{
// State's key press responses
m_currentState->OnKeys(SDL_GetKeyboardState(nullptr));
// Update State
m_currentState->OnUpdate(delta);
// Render State
m_currentState->OnRender();
HandleEvents();
}
delete this;
}
void GameStateManager::HandleEvents(void)
{
// Respond to events
SDL_Event event;
while(SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT) {
m_running = false; // Quit
}
else
{
int size = m_eventHandlers.size();
printf("Whooo! Size: %d\n", size);
for (EventHandler* handler : m_eventHandlers)
handler->OnEvent(event);
}
}
}
I have a class that manages a SDL_Surface for me, and I want to make it so that I don't have to worry about freeing the surface. I have this code so far:
//In Entity.h
class Entity
{
public:
int x, y, width, height;
Entity(std::string);
~Entity();
void render();
private:
SDL_Surface* texture;
};
//In Entity.cpp
Entity::~Entity()
{
printf("Destroying an Entity");
SDL_FreeSurface(texture);
}
//In main.cpp
Entity puppy("puppy.bmp");
void render() {
clearScreen();
puppy.render();
}
int main (int argc, char **argv) {
printf("started");
init();
bool done = false;
while(!done)
{
...
// Draw the screen
printf("About to render");
render();
SDL_Flip(screen);
}
SDL_Quit();
return 0;
}
When I run it, I get Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000260
0x000000010002fd9b in SDL_DisplayFormat () Am I correct in assuming that the destructor is getting called early and it's trying to render a NULL texture? The code works fine if I don't have the destructor and just waste memory. I've also tried it with puppy being a local variable and passing it to render, but that doesn't help.
EDIT: The code runs for only a second, then crashes. It doesn't wait to exit the loop. Also, stepping through the program with gdb reveals the puppy to be drawn at least once for some reason. I've uploaded the full source here: http://dl.getdropbox.com/u/2223161/sdlgame.zip
This is a global variable:
Entity puppy("puppy.bmp");
it gets destroyed after your main() ends, so your SDL_FreeSurface gets called after SDL_Quit(). Is it valid? Check with documentation.
You're looking at the wrong end of the problem. Your code ran for me after I moved the initialization of puppy into main.
By placing puppy as a global object, its constructor runs prior to SDL_Init. The constructor calls load_image, which calls SDL_DisplayFormat. The documentation warns:
You have to call SDL_Init before using the SDL_DisplayFormat function. If you don't, your program will crash with an access violation.
http://sdl.beuc.net/sdl.wiki/SDL_DisplayFormat
Of course, you should also ensure the destructor is called prior to SDL_Quit(), as is proper, though that's not what's causing your access violation at the moment.