C++ destructor called early - c++

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.

Related

C++: Segmentation fault - Calling function through std::vector<> using a virtual function and abstract class

This may be a total obvious error for some, but I can't seem to find out why this segmentation fault happens.
I do understand that segmentation faults occur when accessing an address that my program should not access.
First, I have this base-class called "UiObject":
class UiObject {
private:
public:
UiObject();
virtual void render(char * imageBuffer) = 0;
};
Then, I am deriving multiple other classes from the UiObject class:
For example, the ProgressBar class:
class ProgressBar : public UiObject {
private:
int x,y; // Position der ProgressBar auf dem Bildschirm (oben links) (Pixeln)
int width,height; // Breite und Höhe in Pixeln
public:
int maxProgress; // Maximal zu erreichner Fortschritt
long progress; // Fortschritt aktuell
ProgressBar(); // Constructor
void render(char * framebuffer); // Rendermethode
};
Now, these objects are managed and rendered by an UiManager.
The function renderDisplay() is a thread created with std::thread:
void UiManager::renderDisplays() {
printf("[RENDER] Render thread has been started\n[RENDER] (%x)\n", this);
while(!this->shouldStop) {
// Removed code that manages the timing of this function (running approximately 60FPS)
// Rendering:
for(Display d: displayArray) {
char * framebuffer = d.getFrameBuffer();
printf("Framebuffer: %x\n", framebuffer);
printf("uiArray: %x\n", uiArray);
printf("&uiArray: %x\n", &uiArray);
for(UiObject* pObject : uiArray) {
printf("[RENDER] (%x) Rendering Object...", pObject);
pObject->render(framebuffer);
}
d.renderDisplay();
}
}
}
As you can see, for every added Display I am retrieving the framebuffer. I'm opening the /dev/fbX files so i can draw directly onto the screen. This all works fine. d.getFramebuffer() returns a char * pointer so i can manipulate the pixels, which is then passed into the render(char * framebuffer) function of any UiObject.
However, this function call is creating a segfault, and I can't understand why.
There are sometimes when it works and just runs until the thread should stop, and sometimes it crashes immidiately after the first render-function call.
I add the UiObjects to the UiManager using this:
ProgressBar pBar;
pBar.maxProgress = 60*15;
pBar.progress = 1;
uiArray.push_back(&pBar);
The UiManager has this as its class-definition:
class UiManager {
private:
char ttyfd; // TTY File Descriptor.
std::thread uiManagerThread;
std::chrono::system_clock::time_point timeA;
std::chrono::system_clock::time_point timeB;
std::chrono::duration<double, std::milli> work_time;
public:
std::vector<Display> displayArray;
std::vector<UiObject*> uiArray;
bool shouldStop;
bool displayFPS;
UiManager();
void stop();
void renderDisplays();
void addDisplay(Display d);
void startThread();
void stopThread();
};
Now I'm wondering why this is.
According to the cppreference https://en.cppreference.com/w/cpp/language/abstract_class and their documentation about abstract classes, I'm not allowed to have the =0; in my UiObject class.
If I remove it, I will get compiler warnings during linking with the message "undefined reference to vtable for UiObject".
What have I done wrong?
I suspect that the std::vector and the for-loop are not quite working in the UiManager.
Im using g++ on debian as my compiler.
My console output:
[RENDER] Render thread has been started
[RENDER] (6ea609f0)
Framebuffer: e09f0010
uiArray: e09eed20
&uiArray: 6ea60a30
./run.sh: Zeile 21: 25018 Speicherzugriffsfehler ./a.out
It also does not even jump into the ProgressBar render routine. I also commented out the contents of the render-function, therefore i can only suspect that specific function call.
= 0 for an abstract base class is correct.
However,
ProgressBar pBar;
//...
uiArray.push_back(&pBar);
is not.
pBar will be destroyed once the scope in which it is declared is left and then trying to dereference the dangling pointer later in renderDisplays is undefined behavior.
You need to create the object with new, or better store std::unique_ptr<UiObject> in the vector and create objects with std::make_unique<ProgressBar>().
Also, UiObject needs a virtual destructor: virtual ~UiObject() = default;
Otherwise destroying objects through the base class pointer will cause undefined behavior.
Then there seems to be also no synchronization between the access to uiArray in the two threads.
Accessing uiArray for modification and read in two threads without synchronization is a data race and undefined behavior.
You need to add a mutex and lock it when accessing uiArray in both threads.
I add the UiObjects to the UiManager using this:
It looks like you're allocating these ProgressBar objects on the stack. I don't have all of your code, but I wonder if this is being done in another function and then the stack doesn't exist when they're being used. This would explain the intermittent error as sometimes the stack for that function call still exists. To fix this, I'd allocate the ProgressBar objects on the heap:
ProgressBar* pBar = new ProgressBar();
pBar->maxProgress = 60*15;
pBar->progress = 1;
uiArray->push_back(pBar);

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.

C++ Visual Studio Release build unused code crash

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.

'&' : illegal operation on bound member functions expression Thread

I'm trying to run a member function in a thread, but I get the error illegal operation on bound member function, I'm not sure what I'm doing wrong. I would like if someone could explain me what I'm doing wrong and why I get this error, and give me an example of how to fix it. The code looks like this:
void GameWorld::SetupWorld()
{
// create the window (remember: it's safer to create it in the main thread due to OS limitations)
RenderWindow window(VideoMode(800, 600), "OpenGL");
// deactivate its OpenGL context
window.setActive(false);
// launch the rendering thread
Thread thread(&Render, &window);//This line gives the error
thread.launch();
}
void GameWorld::Render(RenderWindow* window)
{
Texture texture;
Sprite sprite;
if (!texture.loadFromFile("sprite.png"))
{
}
sprite.setTexture(texture);
// the rendering loop
while (window->isOpen())
{
// clear the window with black color
window->clear(Color::White);
// draw everything here...
window->draw(sprite);
// end the current frame
window->display();
}
}
You have a serious case of undefined behavior from passing a pointer to a local variable to the thread.
Once the function returns, that variable will go out of scope, and the object will be destructed, leaving you with a pointer to unallocated memory.
You also have a problem if the Render function is not static, because non-static member functions have a hidden first argument that becomes the this pointer inside the member function. It's probably this problem that the compiler is complaining about.
A possible third problem might be that once the SetupWorld function returns, your thread variable will also go out of scope and be destructed. Depending on what threading framework you're using it might kill the thread quite unexpectedly.
To fix the compilation error change your complaining line to Thread thread(&GameWorld::Render, &window)
However for completeness you should read #Some programmer dude's answer.

Application breaks on CCriticalSection::Lock

I am upgrading an application from VC6 to VS2010 (Legacy Code). The application runs as it should in VC6 but after converting the project to VS2010 I encountered some problems.
On exiting the application, the program breaks while attempting to lock on entering a critical section.
The lock count usually alternates from -1(Unlocked) to -2(Locked) but just before the program crashes, the lock count is 0.
g_RenderTargetCriticalSection.Lock();// Breaks here
if (g_RenderTargets.Lookup(this, pRenderTarget))
{
ASSERT_VALID(pRenderTarget);
g_RenderTargets.RemoveKey(this);
delete pRenderTarget;
}
g_RenderTargetCriticalSection.Unlock();
Here is the CCriticalSection::Lock() function where ::EnterCriticalSection(&m_sect); fails. I found it strange that on failing, the lock count changes from 0 to -4??
_AFXMT_INLINE BOOL (::CCriticalSection::Lock())
{
::EnterCriticalSection(&m_sect);
return TRUE;
}
If anyone has encountered anything similar to this, some insight would be greatly appreciated. Thanks in advance.
The comments indicate this is a file-scope object destructor order issue. There are various ways you could address this. Since I haven't seen the rest of the code it's difficult to offer specific advice, but one idea is to change the CS to live in a shared_ptr and have your CWnd hold onto a copy so it won't be destroyed prematurely. e.g.:
std::shared_ptr<CCriticalSection> g_renderTargetCriticalSection(new CCriticalSection());
Then in your window class:
class CMyWindow : public CWnd
{
private:
std::shared_ptr<CCriticalSection> m_renderTargetCriticalSection;
public:
CMyWindow()
: m_renderTargetCriticalSection(g_renderTargetCriticalSection)
{
// ...
}
~CMyWindow()
{
// guaranteed to still be valid since our shared_ptr is keeping it alive
CSingleLock lock(m_renderTargetCriticalSection.get(), TRUE);
// ...
}
// ...
};
The issue was that the application's Main Window was being destroyed after the application's global object was destroyed. This meant that the g_renderTargetCriticalSection was already Null when the main window was trying to be destroyed.
The solution was to destroy the Application's main window before it's global object (CDBApp theApp) calls ExitInstance() and is destroyed.
int CDBApp::ExitInstance()
{
LOGO_RELEASE
//Destroy the Main Window before the CDBApp Object (theApp) is destroyed.
if(m_Instance.m_hWnd)
m_Instance.DestroyWindow();
return CWinApp::ExitInstance();
}
This code doesn't make sense:
int CDBApp::ExitInstance()
{
LOGO_RELEASE
//Destroy the Main Window before the CDBApp Object (theApp) is destroyed.
if(m_Instance.m_hWnd)
m_Instance.DestroyWindow();
return CWinApp::ExitInstance();
}
m_Instance is a handle, not a class, so it can't be used to call functions!