Mysterious std::list::size() mismatch - c++

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);
}
}
}

Related

Mysterious C++ threading crash

The following code strangely crashes when entering the run function. None of the printfs trigger, and single-stepping into the function will cause a crash. Is it undefined behaviour, or a compiler bug? I'm on MacOS compiling with Apple clang 12.0.0. It crashes with EXC_BAD_ACCESS (code = 2).
#include <iostream>
#include <thread>
#include <vector>
struct Chunk {
// the array must be this big
// other array sizes don't trigger the bug consistently
uint8_t array[524288];
};
std::thread generator_thread;
std::mutex generator_lock;
std::vector<Chunk*> to_generate;
std::condition_variable data_ready;
std::atomic<bool> running;
void begin();
void run();
void begin() {
running = true;
auto func = [] {
run();
};
generator_thread = std::thread(func);
}
void run() {
printf("Running in generator\n");
while (running) {
printf("Running in loop\n");
Chunk *task;
// take a chunk from the queue
{
std::unique_lock<std::mutex> lock(generator_lock);
data_ready.wait(lock, [] { return to_generate.size() > 0 || !running; });
if (!running) break;
task = to_generate.back();
to_generate.pop_back();
}
printf("deref chunk\n");
// Despite never being executed in this example, this line merely existing
// will cause a crash when entering the run_generator function.
Chunk chunk = *task;
// *task.chunk;
// ^^^ Only having the line above will not trigger the bug; it must be assigned
}
}
int main(int argc, const char *argv[]) {
begin();
while (true) {
printf("run\n");
}
return 0;
}
So, when you change your function to pre-reserve a stack frame with space for a half-megabyte object ... it crashes right at the start of the function when setting up that stack frame?
That's probably because you made sizeof Chunk equal to the entire default OSX thread stack size of 512Kb. If you single-step into the function, you should be able to see the instruction that triggers the fault, and it will likely be part of the stack frame setup/function preamble.
All of this is implementation-specific (the stack frames, the per-thread stack size), but putting really big things on the stack is generally a bad idea.

Why is the debugger throwing "read access violation. this was nullptr" exception?

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.

Run boolean at start of thread causes jumping behaviour between instructions

Foo.h
#pragma once
#include <stdint.h>
#include <cstddef>
#include <thread>
#include <mutex>
#include <shared_mutex>
#include <atomic>
class Foo: public FooAncestor
{
private:
std::atomic_bool start = false;
//I do a shared mutex on the currentValue,
//but I took it out in order to make sure that it was not part of the problem
mutable std::shared_mutex valueMutex;
float currentValue = 0.0;
public:
Foo();
void Start();
inline float GetValue() { return currentValue; }
};
Foo.cpp
#include "Foo.h"
using namespace std::chrono_literals;
Foo::Foo()
{
//setting up things not related to the subject
}
void Foo::Start()
{
std::thread updateThread( [=]()
{
start = true;
while( start )
{
//a whole bunch of commented out code which doesn't make any difference to this
std::this_thread::sleep_for( 200ms );
currentTemp += 1;
}
} );
updateThread.detach();
}
Main.cpp
int main()
{
std::cout << "hello from PiCBake!\n";
int i = 0;
//a bunch of additional setup code here, not related to this class
Foo foo = Foo();
foo.Start();
for( ;;)
{
//this part is just for testing of the class and has no actual function
std::cout << max.GetTemp() << std::endl;
delay( 500 );
if( ++i == 10 )
i = 0;
}
return 0;
}
Whenever I include this, or a separate test at the beginning of the updateThread part (like: if(!run) return;) the flow of the code does weird things. In debugging, it keeps jumping to the part where 'run' is being tested, even jumping out of the while loop when run is set in the thread, but the behavior is the same when run is set before the thread is created.
If the thread is very long it actually never gets to finish at all. Whenever I remove the variable 'run' and replace it with "true" all works as expected. If I replace the "while(run)" with "while(true)", but test 'run' right after in an if-statement, the same thing happens.
Tried making run atomic, tried a bunch of other things, removing everything etc.
Please note that I didn't yet implemented a thread-exit condition. "run" could be set to false in the destructor or something in order to quit the thread. But that's not really the issue.
Update:
It must have been late, and I was probably going around in circles. It seems that changing the start value to atomic already solved it, either way, it works and I have no ^&*() clue what was going wrong...

C++ Updating data and rendering

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?

Alternative to a function pointer with reference capture

I'm writing an event handler that listens for key presses, then calls a handler on any pressed keys. My goal was to allow something like this:
Entity player(0, 0);
EventHandler eh([&](char c) {
switch (c) {
case 'W': {
player.moveBy(0,-1);
break;
}
case 'S': {
player.moveBy(0, 1);
break;
}
case 'A': {
player.moveBy(-1, 0);
break;
}
case 'D': {
player.moveBy(1, 0);
break;
}
}
});
where an Entity is just a movable point-like object.
I was all set, then I realized that lambdas with referential captures can't be made into a function pointer (the reason makes sense, in retrospect).
The only alternative I could find was to use std::/boost::function, but the syntax is rather ugly, and apparently they come with a decent amount of overhead.
What's a good alternative to this system? I want to be able to pass in some kind of "handler" to EventHandler that accepts a character, and is capable of carrying out side effects on some external scope.
In the below source, LockedQueue is a FIFO queue that's been made thread safe using mutexes.
EventHandler.h:
#ifndef EVENT_HANDLER_H
#define EVENT_HANDLER_H
#include <vector>
#include <atomic>
#include "LockedQueue.h"
class EventHandler {
typedef void(*KeyHandler)(char);
std::atomic<bool> listenOnKeys = false;
std::vector<char> keysToCheck;
LockedQueue<char> pressedKeys;
KeyHandler keyHandler = nullptr;
void updatePressedKeys();
void actOnPressedKeys();
public:
EventHandler();
EventHandler(KeyHandler);
~EventHandler();
void setKeyHandler(KeyHandler);
void setKeysToListenOn(std::vector<char>);
void listenForPresses(int loopMSDelay = 100);
void stopListening();
};
#endif
EventHandler.cpp:
#include "EventHandler.h"
#include <windows.h>
#include <WinUser.h>
#include <thread>
#include <stdexcept>
EventHandler::EventHandler() {
}
EventHandler::EventHandler(KeyHandler handler) {
keyHandler = handler;
}
EventHandler::~EventHandler() {
stopListening();
}
void EventHandler::updatePressedKeys() {
for (char key : keysToCheck) {
if (GetAsyncKeyState(key)) {
pressedKeys.push(key);
}
}
}
void EventHandler::actOnPressedKeys() {
while (!pressedKeys.empty()) {
//Blocking if the queue is empty
//We're making sure ahead of time though that it's not
keyHandler(pressedKeys.waitThenPop());
}
}
void EventHandler::setKeyHandler(KeyHandler handler) {
keyHandler = handler;
}
void EventHandler::setKeysToListenOn(std::vector<char> newListenKeys) {
if (listenOnKeys) {
throw std::runtime_error::runtime_error(
"Cannot change the listened-on keys while listening"
);
//This could be changed to killing the thread by setting
// listenOnKeys to false, changing the keys, then restarting
// the listening thread. I can't see that being necessary though.
}
//To-Do:
//Make sure all the keys are in upper-case so they're
// compatible with GetAsyncKeyState
keysToCheck = newListenKeys;
}
void EventHandler::listenForPresses(int loopMSDelay) {
listenOnKeys = true;
std::thread t([&]{
do {
updatePressedKeys();
actOnPressedKeys();
std::this_thread::sleep_for(std::chrono::milliseconds(loopMSDelay));
} while (listenOnKeys);
});
t.join();
}
void EventHandler::stopListening() {
listenOnKeys = false;
}
EDIT:
Whoops. Note that listenForPresses is "broken" because I'm joining inside the function, so control never leaves it. I'm going to need to figure out a workaround. Doesn't change the question though, but the code isn't testable in it's current state.
The only alternative I could find was to use std::/boost::function, but the syntax is rather ugly, and apparently they come with a decent amount of overhead.
The overhead is decent compared to an inlinable function, but it's measured in nanoseconds. If you're only calling the function 60 times a second, the overhead is immeasurable.
That said, if you need to be able to change the event handler at any time, your only alternative is virtual method calls, with similar overhead. The performance impact of these choices are explored thoroughly in this article: Member Function Pointers and the Fastest Possible C++ Delegates.
If you are happy to restrict the EventHandler object to executing a single block of code defined at compile-time, use templates to store an instance of the compiler's generated type for the lambda; this should allow the compiler to perform more optimisations, as it can know for sure what code is being called. In this case, KeyHandler becomes a template type, and the type of a lambda can either be found with the decltype keyword:
template <class KeyHandler>
class EventHandler {
// elided
}
void EventLoopDecltype() {
Entity player(0, 0);
auto myEventHandler = [&](char ch) { /* elided */ };
EventHandler<decltype(myEventHandler)> eh(myEventHandler);
}
or (more conveniently, for the caller) inferred as an argument to a template function:
template <class KeyHandler>
EventHandler<KeyHandler> MakeEventHandler(KeyHandler handler) {
return EventHandler<KeyHandler>(handler);
}
void EventLoopInferred() {
Entity player(0, 0);
auto eh = MakeEventHandler([&](char c) {
// elided
});
}
std::function and boost::function do not come with any overhead that's remotely meaningful considering how light your usage of them would be in this case. You've made a critical error by discarding the solution before determining that the purported downsides actually apply to you.
You could of course also use a template as described in the other answer, but there's really no need to.