I have added a image (tiled) as a background to a class inheriting from wxPanel
Inside the constructor, the second line below is causing memory leakage, (reported in debug mode)
wxImage bg(_("images/textures/icobbg8.jpg"), wxBITMAP_TYPE_JPEG);
SetBackgroundBitmap(wxBitmap(bg));
If i comment the SetBackgroundBitmap memory leak is no longer reported.
Note - During debugging, and after viewing call stack i rounded on this statement.
Please tell me, how to overcome memory leak.
Your should call SetBackgroundBitmap(wxNullBitmap)
in your destructor
Class MyPanel:public wxPanel
{
MyPanel(wxWindow* parent, int x, int y, int w, int h);
~MyPanel();
};
MyPanel::~MyPanel()
{
SetBackgroundBitmap(wxNullBitmap); //set null bitmap backgrond, so not
//reference bg to overcome the leak
}
When the constructor exits, the wxImage bg will be destroyed. However, the class still exists and the background image is still needed.
Try changing the bg from a local to an attribute of the class.
Related
I've recently begun to dip my toes into DerelictGLFW. I have two classes, one of them a Window class, and another an InputHandler class (a event manager for window events). In my cursor position callback, I take the window user pointer and try to set the position, but I get an Access Violation Error immediately upon attempting to set any value outside of the callback and GLFW. GLFW is initialized, and does not report any errors. Thank you for your time.
Class Window
{
private:
double cursorX;
...other stuffs...
#property
void cursorX(double x) nothrow
{
cursorX = x;
}
}
extern(C) void mousePosCallback(GLFWwindow* window, double x, double y)
{
Window* _window = window.userPointer
//userPointer is a static function that gets the window user pointer
//and casts it to a Window*
_window.cursorX = x;
}
static Window* userPointer(GLFWwindow* window)
{
return cast(Window*) glfwGetWindowUserPointer(window);
}
Edits:
Added extern(C) to callback, error persists.
Corrected "immediately upon entering the callback" to "immediately upon attempting to set any value outside of the callback and GLFW".
Added userPointer function to question
mousePosCallback must be declared in a extern(C) block. This is to make the calling convention match.
extern (C) void mousePosCallback(GLFWwindow* window, double x, double y)
{
Window* _window = window.userPointer
//userPointer is a static function that gets the window user pointer
//and casts it to a Window*
_window.cursorX = x;
}
It seems I have discovered the source of the error. During initialization of the window, I attempt to set the user pointer with this. I'm not sure why, but moving it into a different function that is not called from the constructor appears to remedy the problem. The problem is solved, but could anyone help me to understand why? It seems rather odd to me.
I am helping program a game in c++ for the Nintendo DS (It has about 3MB of RAM). For all the menus in the interface, a "button" used to be created by calling void function that sets the background tiles to a button. There are at least 30 buttons throughout the interface. Now I've created a button class that stored its position, label, along with other data values. Now my question is:
Will all these new button objects affect the RAM usage (Or other performance aspects) after the program leaves the object's scope?
Or will the object automatically be discarded once the program leaves the function it was created in?
Here is some code:
#include "Button.h"
void titlescreen() //Called to create main menu
{
Button singlePlayer = Button(4, 5, "Single Player");
//Creates button at coord (4,5)
Button multiPlayer = Button(4, 8, "Multi Player");
bool chosen = false; //Whether an option has been clicked
while(!chosen)
{
//Menu stuff here
}
}
Button.h:
#include <stdio.h>
#ifndef BUTTON_H
#define BUTTON_H
class Button
{
public:
int length;
int x, y;
bool isColored;
void setColored(bool);
void setDefault();
button(int, int, const char * const); //Constructor
button(int, int, const char * const, int); //Constructor
};
#endif /* BUTTON_H */
Though your terminology is lacking, the code you wrote allocates the objects "on the stack", and so only last as long as your scope.
In fact, you can write it even more concisely:
//Button singlePlayer = Button(4, 5, "Single Player"); // bad, uses the copy constructor
Button singlePlayer(4, 5, "Single Player"); // uses just a constructor call
Anyway an important thing you should be aware of is that since you're using the "stack" to hold your objects, whether or not you're "allocating" or "freeing" them your "RAM usage" will not change. The "stack" in most implementations is a pre-allocated chunk of memory that never expands, it just throws stack overflow exceptions (or your framework equivalent, I think C has a signal for it?) when it fills up. So generally using your "stack" up on objects is a bad idea.
Yes, objects are destroyed when they go out of scope (i.e. the destructor of the Buttons are called). So singlePlayer and multiPlayer will be destroyed when program returns from the function titlescreen.
So, as long as the destructor of Button cleans up everything, the buttons won't affect the RAM usage after the function returns.
Also, you should include the C++ header file cstdio instead of the c-header stdio.h.
I have a Class Player like this:
class Player
{
public:
Player();
~Player(void);
Sprite *sprite;
Sprite *rocket;
void draw(int x, int y, SpaceInvaders *system);
}
and in Player.cpp
void Player::draw(int x, int y, SpaceInvaders *system) {
sprite = system->createSprite("data/player.bmp");
sprite->draw(x, y);
}
Player::~Player(void)
{
sprite->destroy();
rocket->destroy();
}
This draw method is called in a while loop in main:
player.draw(int(xPos), 480-32, system);
The game runs fine until I X the window. That's when I get "Access violation reading location 0x00000004" on the first line in the Player::draw method.
I've read that it might be due to passing a null pointer or null reference but I don't know how to fix this.
Would appreciate any help, thanks!
It's most probably because when closing the window, something gets destroyed while draw is called - most probably the system pointer.
In your case, draw should never be called when the user wants to close its window (unless the x calls another function to start a closing process of some sort). The best would be to first validate that system is not NULL or even better, use a shared pointer to ensure it is still valid when being used. Afterwwards, you shoiuld ensure that draw is not called when the window is closing - that should be done when calling the draw function (or above depending on how you've designed your application.
On a side note, unless you have a caching mechanism (and even that is not the best way to do it), you're recreating your sprite everytime it's being drawn. I suggest you keep a member variable and initialize the sprite in the construtor.
Here's the (relevant) code for my pro::surface class:
/** Wraps up SDL_Surface* **/
class surface
{
SDL_Surface* _surf;
public:
/** Constructor.
** #param surf an SDL_Surface pointer.
**/
surface(SDL_Surface*);
/** Overloaded = operator. **/
void operator = (SDL_Surface*);
/** calls SDL_FreeSurface(). **/
void free();
/** destructor. Also free()s the internal SDL_Surface. **/
virtual ~surface();
}
Now the problem is that in my main function, the object destroys itself (and hence calls the destructor which dangerously free()s the SDL Video Surface!) before the real rendering begins.
int main(int argc, char** argv)
{
...
// declared here
pro::surface screen = SDL_SetVideoMode(320,240,16,SDL_HWSURFACE|SDL_DOUBLEBUF);
// event-handling done here, but the Video Surface is already freed!
while(!done) { ... } // note that "screen" is not used in this loop.
// hence, runtime error here. SDL_Quit() tries to free() the Video Surface again.
SDL_Quit();
return 0;
}
So my question is, is there any way to stop the pro::surface instance from destroying itself before the program ends? Doing memory management manually works though:
/* this works, since I control the destruction of the object */
pro::surface* screen = new pro::surface( SDL_SetVideoMode(..) );
/* it destroys itself only when **I** tell it to! Muhahaha! */
delete screen;
/* ^ but this solution uses pointer (ewww! I hate pointers) */
But isn't there a better way, without resorting to pointers? Perhaps some way to tell the stack to not delete my object just yet?
You violated the Rule of Three, bitch.
pro::surface screen = SDL_SetVideoMode(320,240,16,SDL_HWSURFACE|SDL_DOUBLEBUF);
Is equal to
pro::surface screen = pro::surface(SDL_SetVideoMode(320,240,16,SDL_HWSURFACE|SDL_DOUBLEBUF));
Now double free, because you violated the Rule of Three. So give your class a proper copy constructor/assignment operator, or disallow them and explicitly construct it properly.
Edit: This also explains why your pointer version works fine- because you don't invoke a copy.
Wrap the screen in a special wrapper, that pairs SDL_SetVideoMode with SDL_Quit instead of SDL_FreeSurface.
pro::screen screen(320, 240, 16, SDL_HWSURFACE | SDL_DOUBLEBUF);
// ...
And fix your copy ctor, obviously.
My program keeps crashing when I close the frame. I've narrowed the cause down to two lines of problematic code, but I'm not sure why they're crashing. Here's some of my code:
TetrisFrame.cpp
TetrisFrame::TetrisFrame()
: wxFrame(0, wxID_ANY, "Tetris")
{
statusController_ = new StatusController;
statusController_->setModel(new Statuses);
statusController_->addView(this);
tetrisController_ = new TetrisController;
tetrisController_->setStatusController(statusController_.get()); // Problem one
tetrisController_->setModel(new TetrisModel);
tetrisController_->addView(new Board(this)); // Problem two
}
TetrisFrame class private member variables:
wxSharedPtr<StatusController> statusController_;
wxSharedPtr<TetrisController> tetrisController_;
StatusController class private section:
typedef wxSharedPtr<TetrisFrame> ViewPtr;
wxSharedPtr<Statuses> model_;
std::vector<ViewPtr> views_;
Board class private member variables:
wxSharedPtr<TetrisController> controller_;
relevant TetrisController functions:
void TetrisController::setStatusController(
StatusController* statusControllerPtr)
{
statusController_ = statusControllerPtr;
}
void TetrisController::addView(Board* viewPtr)
{
views_.push_back(ViewPtr(viewPtr));
viewPtr->setControlller(this);
}
Oddly enough problem two wasn't crashing the program until I fixed another problem that was crashing the program. What's wrong with my code?
Keep in mind that wxWidgets does its own form of memory management for widgets. So if you are dynamically allocating the memory for a widget-type, and you then pass the address of that widget to an object that can call delete on it while the parent of that widget is designated by the wxWidgets run-time to destroy that widget when the parent widget is destroyed, then you're going to run into a case of double-deletion, or a case where the parent still thinks the child widget is a valid object when it's not. A shared-pointer type will basically "own" an object ... so make sure that when you dynamically allocate an object and pass it to a shared-pointer type that you are not inadvertently making the pointer "owned" by two different memory-reclaiming pathways.