C++ Member variable losing value after constructor - c++

I'm having a problem in one of my classes. I have these 2 classes, GameApp and Simulation:
GameApp.h
#pragma once
#include "Simulation.h"
class Simulation;
class GameApp {
static GameApp *instance;
public:
~GameApp(void);
static GameApp *initializeContext(const char *gameTitle, const int windowWidth, const int windowHeight);
//void setSimulation(Simulation &simulation) { *(this->simulation) = simulation; }
Simulation *getSimulation() { return simulation; }
static const int TARGET_FPS = 50; // Frames per second
private:
GameApp(void);
Simulation *simulation;
double frameIntervalList[TARGET_FPS]; // A list containing the time to render the last 60 frames
// Other stuff that doesn't matter
Simulation.h
#pragma once
#include <vector>
#include "GameApp.h"
class Simulation {
public:
Simulation(void);
Simulation(const Simulation &copy);
~Simulation(void);
Simulation &operator=(const Simulation &other);
protected:
std::vector<Entity*> *entities;
And, in GameApp.cpp, in the function initializeContext, I have:
#include "GameApp.h"
GameApp *GameApp::instance = NULL;
GameApp::GameApp() {
gamePaused = false;
frameIntervalSum = 0;
this->simulation = new Simulation();
for (int i = 0; i < 60; i++) {
frameIntervalList[i] = 0;
}
}
GameApp *GameApp::initializeContext(const char *gameTitle, const int windowWidth, const int windowHeight) {
instance = new GameApp();
// (...) Rest of initialize funcion
}
The problem is, for some misterious reason, when I call initializeContext, the first line of it calls GameApp's constructor, which creates a new Simulation, which allocates correctly and I get a memory address for the simulation pointer. But when the program exits the constructor of GameApp, in the line right after instance = new GameApp();, if I check the simulator variable on the newly created instance using the debugger, I get the pointer value of 0x00000000, and the Simulation that I just created is gone. This would indeed happen if I was using the stack memory on the constructor, but I'm clearly using new, creating the new Simulation variable in the correct way, I guess. What may be happening here?
Also, there's a commented setSimulation function on the GameApp.h file. When I leave this uncommented, I get the compiler error 2582, "operator= function is unavailable in Simulation". Can this be related to my problem?
EDIT: The problem was indeed the for loop with the hardcoded size. I changed the size of frameIntervalList from 60 to 50 in the header but forgot to change it on the loop. Also updated code to show the declaration of frameIntervalList.

The only code that executes between the initialization of the simulation member variable and the code that comes after the GameApp ctor is the for loop that initialzes frameIntervalList so its initialization with a hardcoded size might overwrite the value of simulation variable if you are unlucky. (Or lucky because it helps you to catch a very ugly bug early!!! :-)

Related

Accessing data of another class whose object was sent as parameter in constructor

I'm working on creating a simulator for RISC.
Below are a different part of codes relevant to my question.
main.cpp
memory* main_memory;
processor* cpu;
main_memory = new memory (verbose); //memory classs implemented correctly
cpu = new processor (main_memory, verbose);
interpret_commands(main_memory, cpu);// takes to commands class
In processor.cpp, I have to access a function of memory class that is public.
memory.cpp:
uint32_t memory::read_word (uint32_t address) {
// some calculation and returns a hex word at address
}
processor.cpp:
#include "memory.h"
void processor::execute(unsigned int num, bool breakpoint_check){
if(some condition){
//call read_word at address
}
}
I do have a parameterized constructor in processor.cpp that has memory class pointer:
processor::processor(memory* main_memory, bool verbose){
}
The question is, how can I call read_word function(of class memory) from the execute function (of class processor)?
Any help would be highly appreciated :)
You just need to store the main_memory* in the constructor as a member variable, so you can use it later in another member function:
processor::processor(memory* main_memory, bool verbose)
: _main_memory(main_memory)
{}
void processor::execute(unsigned int num, bool breakpoint_check){
if(some condition){
_main_memory->read_word(...);
}
}
And add memory* _main_memory = nullptr inside class processor.

C++ Vector read access violation Mylast returned 0x8

I really need help on this one cause I am extremely stuck and have no idea what to do.
Edit:
A lot of you guys are saying that I need to use the debugger but let me be clear I have not used C++ for an extremely long time and I've used visual studio for a grand total of 2 weeks so I do not know all the cool stuff it can do with the debugger.
I am a student at university at the beginning of my second year who is trying to work out how to do something mostly by failing.
I AM NOT a professional coder and I don't have all the knowledge that you people have when it comes to these issues and that is why I am asking this question. I am trying my best to show my issue so yes my code contains a lot of errors as I only have a very basic understanding of a lot of C++ principles so can you please keep that in mind when commenting
I'm only posting this here because I can don't know who else to ask right now.
I have a function called world that is suppose to call my render class to draw all the objects inside of its vector to the screen.
#include "C_World.h"
C_World::C_World()
{
// creates an instance of the renderer class to render any drawable objects
C_Renderer *render = new C_Renderer;
}
C_World::~C_World()
{
delete[] render;
}
// adds an object to the world vector
void C_World::addToWorld(C_renderable* a)
{
world_list.push_back(a);
}
void C_World::World_Update()
{
render->ClearScreen();
World_Render();
}
void C_World::World_Render() {
for (int i = 0; i < 1; i++)
{
//render->DrawSprite(world_list[i]->getTexture(), world_list[i]->get_X, world_list[i]->get_Y());
render->DrawSprite(1, 1, 1);
}
}
While testing I commented out the Sprites get functions in order to check if they were causing the issue.
the renderer sprites are added to the vector list in the constructor through the create sprite function
C_Renderer::C_Renderer()
{
// test sprite: Id = 1
CreateSprite("WhiteBlock.png", 250, 250, 1);
}
I thought this might of been the issue so I had it in other functions but this didn't solve anything
Here are the Draw and create Sprite functions
// Creates a sprite that is stored in the SpriteList
// Sprites in the spriteList can be used in the drawSprite function
void C_Renderer::CreateSprite(std::string texture_name,
unsigned int Texture_Width, unsigned int Texture_height, int spriteId)
{
C_Sprite *a = new C_Sprite(texture_name,Texture_Width,
Texture_height,spriteId);
SpriteList.push_back(a);
size_t b = SpriteList.size();
HAPI.DebugText(std::to_string(b));
}
// Draws a sprite to the X and Y co-ordinates
void C_Renderer::DrawSprite(int id,int x,int y)
{
Blit(screen, _screenWidth, SpriteList[id]->get_Texture(),
SpriteList[id]->getTexture_W(), SpriteList[id]->getTexture_H(), x, y);
}
I even added some test code into the create sprite function to check to see if the sprite was being added too the vector list. It returns 1 so I assume it is.
Exception thrown: read access violation.
std::_Vector_alloc<std::_Vec_base_types<C_Sprite *,
std::allocator<C_Sprite *> > >::_Mylast(...) returned 0x8.
that is the full error that I get from the compiler
I'm really really stuck if there is anymore information you need just say and ill post it straight away
Edit 2:
#pragma once
#include <HAPI_lib.h>
#include <vector>
#include <iostream>
#include "C_renderable.h"
#include "C_Renderer.h"
class C_World
{
public:
C_World();
~C_World();
C_Renderer *render = nullptr;
void World_Update();
void addToWorld(C_renderable* a);
private:
std::vector<C_renderable*> world_list;
void C_World::World_Render();
};
#pragma once
#include <HAPI_lib.h>
#include "C_renderable.h"
#include "C_Sprite.h"
#include <vector>
class C_Renderer
{
public:
C_Renderer();
~C_Renderer();
// gets a pointer to the top left of screen
BYTE *screen = HAPI.GetScreenPointer();
void Blit(BYTE *destination, unsigned int destWidth,
BYTE *source, unsigned int sourceWidth, unsigned int sourceHeight,
int posX, int posY);
void C_Renderer::BlitBackground(BYTE *destination,
unsigned int destWidth, unsigned int destHeight, BYTE *source,
unsigned int sourceWidth, unsigned int sourceHeight);
void SetPixel(unsigned int x,
unsigned int y, HAPI_TColour col,BYTE *screen, unsigned int width);
unsigned int _screenWidth = 1750;
void CreateSprite(std::string texture_name,
unsigned int Texture_Width,unsigned int Texture_height, int spriteId);
void DrawSprite(int id, int x, int y);
void ClearScreen();
private:
std::vector<C_Sprite*> SpriteList;
};
I don't say this lightly, but the code you've shown is absolutely terrible. You need to stop and go back several levels in your understanding of C++.
In all likeliness, your crash is the result of a simple "shadowing" issue in one or more of your functions:
C_World::C_World()
{
// creates an instance of the renderer class to render any drawable objects
C_Renderer *render = new C_Renderer;
}
C_World::~C_World()
{
delete[] render;
}
There are multiple things wrong here, and you don't show the definition of C_World but if this code compiles we can deduce that it has a member render, and you have fallen into a common trap.
C_Renderer *render = new C_Renderer;
Because this line starts with a type this is a definition of a new, local variable, render. Your compiler should be warning you that this shadows the class-scope variable of the same name.
What these lines of code
C_World::C_World()
{
// creates an instance of the renderer class to render any drawable objects
C_Renderer *render = new C_Renderer;
}
do is:
. assign an undefined value to `this->render`,
. create a *local* variable `render`,
. construct a dynamic `C_Renderer` presumably on the heap,
. assign that to the *local* variable `render`,
. exit the function discarding the value of `render`.
So at this point the memory is no-longer being tracked, it has been leaked, and this->render is pointing to an undefined value.
You repeat this problem in several of your functions, assigning new results to local variables and doing nothing with them. It may not be this specific instance of the issue that's causing the problem.
Your next problem is a mismatch of new/delete vs new[]/delete[]:
C_World::~C_World()
{
delete[] render;
}
this would result in undefined behavior: this->render is undefined, and delete[] on a non-new[] allocation is undefined.
Most programmers use a naming convention that distinguishes a member variable from a local variable. Two common practices are an m_ prefix or an _ suffix for members, e.g.
class C_World
{
public:
C_Foo* m_foo; // option a
C_Renderer* render_; // option b
// ...
}
Perhaps you should consider using modern C++'s concept of smart pointers:
#include <memory>
class C_World {
// ...
std::unique_ptr<C_Renderer> render_;
// ...
};
C_World::C_World()
: render_(new C_Renderer) // initializer list
{}
But it's unclear why you are using a dynamic allocation here in the first place. It seems like an instance member would be better:
class C_World {
C_Renderer render_;
};
C_World::C_World() : render_() {}

How to specify c++ static vector size when the size is only known at runtime - Not Needed

I have a class that contains a member that is a vector of floats and needs to be available to all objects of the class. The size of the member won't be known until runtime and I can't figure out how to set the size of the vector.
My first try was to try to set the size in the constructor, but that just memory all messed up. numScores is the number of scores to create that is only known at runtime.
class Window
{
public:
Window ();
private:
vector<float> mScores;
};
vector<float> Window::mScores;
Window::Window ()
{
mScores.resize (numScores);
}
I tried setting the size in the member initialization section of the constructor:
class Window
{
public:
Window ()
private:
vector<float> mScores;
}
vector<float> Window::mScores;
Window::Window ()
: mScores (numScores)
{
}
and got the following error "'std::vector<float, std::allocator<float> > Window::mScore' is a static data member; it can only be initialized at its definition"
So, I moved the setting of the size to where mScores is defined:
class Window
{
public:
Window ()
private:
vector<float> mScores;
}
vector<float> Window::mScores (numScores);
Window::Window ()
{
}
This compiled fine, but when I ran my program and looked at Window::mScores, the size was 0.
I've been trying to track down this problem for a couple of weeks and finally figured out today what the problem is but don't have any idea how to fix it. It would be easy if the numScores was known at compile-time, but unfortunately it is not.
Is there some design pattern or boost-like library that would have something that I could refer to to figure this out?
Any help would be greatly appreciated!
Edit-
Thanks for everyone's input. As I mentioned below, I made a mistake when I copied the Window class over from the computer that the code actually resides on and the compounded that by cutting and pasting the class in the other examples.
With that said, it turns out that I didn't need the static field. I'm in the process of translating FORTRAN (or Fogeytran as I've started calling it) into C++ and was very confused on how the mScores field was being used. Once I realized it wasn't being shared between Windows objects, everything fell into place and is working fine now.
Once again, thanks again for the information.
Since mScores isn't a static member variable, you shouldn't attempt to define it outside of the class. Once that is fixed, it should work as you expect. See below:
class Window
{
public:
Window ()
private:
vector<float> mScores;
}
// mScores isn't static, so this shouldn't be here
// vector<float> Window::mScores;
Window::Window ()
: mScores (numScores)
{
}
From your description it seems that you want to have this vector as a static data member. If so then you can also define a static member function that will resize the vector when you will know its actual size.
For example
#include <vector>
class Window
{
public:
Window() = default;
static void SetSize( std::vector<float>::size_type n ) { mScores.resize( n ); }
private:
static std::vector<float> mScores;
};
std::vector<float> Window::mScores;
int main()
{
Window::SetSize( 10 );
}
If you want that this finction may rresize the vector only once you can define it the following way
static void SetSize( std::vector<float>::size_type n )
{
static bool resized;
if ( !resized )
{
mScores.resize( n );
resized = true;
}
}

static member is not being updated

I've come across very strange behavior. In my class I have QFileSystemModel declared as a static variable and this variable is getting initialized in the ctor, and it works, but as soon as I try to update its state (via some method from this class) this seems to not have any effect. But as soon as I change this variable to non-static everything works as it should. What is it about static variables that I'm missing?
class X:public QDialog
{
Q_OBJECT
static QFileSystemModel* model_;
public:
void update();
};
//cpp file
X::QFileSystemModel* model_
X::X()
{
model_ = new QFileSystemModel(this);
}
void X::update()
{
model_->setNameFilters("*.h");//this will have absolutely no effect unless I make
//model_ non static
}
You need to do it like this, to prevent multiple initialisations of model_:
//cpp file
X::QFileSystemModel* model_ = 0; // Not strictly necessary, but good for clarity
X::X()
{
if (model_ == 0) model_ = new QFileSystemModel(this);
}
Since you are creating a new model_ for every new instance of your class X (each time the constructor is run) the problem you are describing seems to boil down to something a long the lines of; overwriting.
It's probably getting overwritten by another freshly created instance after you set some state in X::update.
That's the best answer I can give you without any more information regarding the matter.
Simple sample solution
struct Obj {
Obj () {
std::cerr << "model_: " << *model_ << std::endl;
++(*model_);
}
static int * model_;
};
int * Obj::model_ = new int (); // initialize the static member
int
main (int argc, char *argv[])
{
Obj a, b, c;
}
Typo?
I'm guessing this part of your snippet contains a typo, since a constructor cannot have a return type.
X::QFileSystemModel* model_
X::X()
{
model_ = new QFileSystemModel(this);
}

std::string constructor corrupts pointer

I have an Entity class, which contains 3 pointers: m_rigidBody, m_entity, and m_parent. Somewhere in Entity::setModel(std::string model), it's crashing. Apparently, this is caused by bad data in m_entity. The weird thing is that I nulled it in the constructor and haven't touched it since then. I debugged it and put a watchpoint on it, and it comes up that the m_entity member is being changed in the constructor for std::string that's being called while converting a const char* into an std::string for the setModel call. I'm running on a Mac, if that helps (I think I remember some problem with std::string on the Mac). Any ideas about what's going on?
EDIT: Here's the code for GEntity:
GEntity::GEntity(GWorld* world, unsigned long int idNum) {
GEntity(world, idNum, btTransform::getIdentity());
}
GEntity::GEntity(GWorld* world, unsigned long int idNum, btTransform trans) : m_id(idNum), m_trans(trans), m_world(world) {
// Init unused properties
m_rigidBody = NULL;
m_entity = NULL; // I'm setting it here
m_parent = NULL;
// Find internal object name
std::ostringstream ss;
ss << "Entity" << idNum << "InWorld" << world;
m_name = ss.str();
// Create a scene node
m_sceneNode = m_world->m_sceneMgr->getRootSceneNode()->createChildSceneNode(m_name+"Node");
// Initialize the SceneNode's transformation
m_sceneNode->setPosition(bv3toOv3(m_trans.getOrigin()));
m_sceneNode->setOrientation(bqToOq(m_trans.getRotation()));
}
void GEntity::setModel(std::string model) {
m_model = model;
// Delete entity on model change
if(m_entity != NULL) { // And by the time this line comes around, it's corrupt
m_world->m_sceneMgr->destroyEntity(m_entity);
m_entity = NULL;
}
// Create new entity with given model
m_entity = m_world->m_sceneMgr->createEntity(m_name+"Ent", model);
// Apply a new rigid body if needed
if(m_rigidBody != NULL) {
initPhysics();
}
}
void GEntity::initPhysics() {
deinitPhysics();
}
void GEntity::deinitPhysics() {
if(m_rigidBody != NULL) {
m_world->m_dynWorld->removeRigidBody(m_rigidBody);
delete m_rigidBody;
m_rigidBody = NULL;
}
}
And here's the definition of GEntity:
class GEntity : public btMotionState {
public:
GEntity(GWorld* world, unsigned long int idNum);
GEntity(GWorld* world, unsigned long int idNum, btTransform trans);
void setModel(std::string modelName);
void initPhysics();
void deinitPhysics();
void getWorldTransform(btTransform& worldTrans) const;
void setWorldTransform(const btTransform &trans);
void parent(GEntity* parent);
protected:
unsigned long int m_id;
// Physics representation
btTransform m_trans;
btRigidBody* m_rigidBody;
// Graphics representation
Ogre::SceneNode* m_sceneNode;
Ogre::Entity* m_entity;
// Engine representation
GWorld* m_world;
GEntity* m_parent;
std::string m_name;
std::string m_model; // Used to find physics collision mesh
};
And here's the code calling setModel:
// Setup game world
GWorld* world = new GWorld(win);
GEntity* ent = world->createEntity();
ent->setModel(std::string("Cube.mesh"));
Your problem is that this line is constructing a nameless temporary GEntity inside the constructor body for a different GEntity. The temporary is then thrown away once the statement completes and no further initialization of the non-temporary GEntity is performed.
GEntity(world, idNum, btTransform::getIdentity());
If you want to share some initialization code between your two constructors you should create a member function that performs the required actions and call this function from both constructors. C++ doesn't (currently) allow you to delegate initialization from one constructor to a different constructor or call two constructors on the same object.
My best guess is that the problem is in GWorld::createEntity. If you're creating a local GEntity on the stack and returning a pointer to it, you'll see something like what you describe, as the GEntity is destroyed when GWorld::createEntity returns and the memory is reused for the temp string constructed to pass to setModel
Edit
I see you've added more code, including the definition of createEntity. That looks fine, but I would still suggest looking for some way in which the GEntity you're seeing the problem with gets deleted (and the memory reused for a string) before you call setModel.
One solution I have found is to use string.resize(n), which will resize the function. However, I do not know why this works, and I feel my problem is with my code since std::string is part of the standard C++ library.
I can't find the answer but I can make a suggestion that will help catch the problem:
Add assertions. A lot of assertions. Each one of those functions really need some assertions at least at their beginning. That will certainly help you catch wrong states early.
And by the way, you should use a constant reference as parameter of your setModel() function.
In C++ you can not call a constructor from within a constructor.
Try
GEntity::GEntity(GWorld* world, unsigned long int idNum) : GEntity(world, idNum, btTransform::getIdentity() {}