variables alteration in c++ - c++

i got a ridiculous problem.
i have a class within inside an array member.i have a get method and a set method for the array.
the problem is that i call the set(to update) method to change the variables within the array and i see with the debugger that the variables do actually update.then when i call immediately the get method just after the set method i found the variables of the array been changed back to their ancient values.
here is the code approximately :
object.updatFunction();//sort of set method
//nothing in between
Type variable=object.getFunction();
added code:
void Cube::updtCornersNextToCentr()
{
int iHalfSide=m_SideSize/2;
int centerX(m_Center.x()),centerY(m_Center.y()),centerZ(m_Center.z());
m_CubeCornerVertices[0].setX(centerX-iHalfSide);
m_CubeCornerVertices[0].setY(centerY+iHalfSide);
m_CubeCornerVertices[0].setZ(centerZ-iHalfSide);
m_CubeCornerVertices[1].setX(centerX+iHalfSide);
m_CubeCornerVertices[1].setY(centerY+iHalfSide);
m_CubeCornerVertices[1].setZ(centerZ-iHalfSide);
//.......
m_CubeCornerVertices[7].setX(centerX+iHalfSide);
m_CubeCornerVertices[7].setY(centerY-iHalfSide);
m_CubeCornerVertices[7].setZ(centerZ+iHalfSide);
}
QVector3D * Cube::getCubeCornerVertices()const
{
static QVector3D temp[8];
for(int i=0;i<8;i++)
{
temp[i]=m_CubeCornerVertices[i];
}
return &temp[0];
}

The problem was really ridiculous, i didn’t want to let this post ambiguous.it’s a very beginner fault and it’s all about a missing « & » that caused me to update a copy.
Actually i did above simplify write the next code :
object.updatFunction();//sort of set method
//nothing in between
Type variable=object.getFunction();
And the more real code was something like:
m_WorldSpace->getCube().updtCornersNextToCentr()
//nothing in between
const QVector3D corners[8]=m_WorldSpace->getCube().getCubeCornerVertices();
all the problem was in the getCube() function which instead of being something like this :
Cube& WorldSpace::getCube()//here is the missing "&"
{
return m_Cube;
}
I wrote this
Cube WorldSpace::getCube()//this caused to get and update just a temporary copy
{
return m_Cube;
}
someone can say that i got multiple levels of getters which blinded me.
thank you.

Related

I get an uninitialized object from a pointer

So i have some troubles getting pointers to work with SFML shapes. I'm not sure if it has something to do with SFML or if I'm doing anything wrong.
In Draw() x(a ControlWindow) does not contain valid values, it only shows "???" as shown here. However the m_controls(map) contains the correct values for the control object.
I'm quite new to C++ so any help would be greatly appreciated.
Exception
Exception thrown at 0x60B26EE5 (sfml-graphics-2.dll) in OokiiUI.exe: 0xC0000005: Access violation reading location 0x00000000.
Main
vector<WindowControl> windowControls;
void Draw ();
int main ()
{
RectangleShape rect(Vector2f(120,120));
WindowControl windowControl(nullptr,0);
Control testControl(&windowControl,1);
testControl.SetShape(&rect);
windowControl.AddControl(testControl);
windowControls.push_back(windowControl);
return 0;
}
WindowControl
class WindowControl : Control
{
public:
WindowControl ( WindowControl * windowControl, uint64_t uint64 )
: Control ( windowControl, uint64 )
{
}
void AddControl(Control control)
{
m_controls.insert_or_assign(control.GetId(), control);
m_controlPtrs.push_back(&control);
}
vector<Control*>* GetControls()
{
return &m_controlPtrs;
}
private:
map<uint64_t, Control> m_controls;
vector<Control*> m_controlPtrs;
};
Draw
for (auto x : windowControls)
{
vector<Control*> *controlPtrs = x.GetControls();
window->draw(x.GetControl(0)->GetShape());
}
There is a problem here:
void AddControl(Control control)
{
m_controls.insert_or_assign(control.GetId(), control);
m_controlPtrs.push_back(&control);
}
You add the address of the parameter control which is destroyed when the function ends. It looks like you want to add the address of the copy that you add to your map like this:
void AddControl(Control control)
{
m_controls.insert_or_assign(control.GetId(), control);
// don't use the parameter here, use the copy you put in the map
m_controlPtrs.push_back(&m_controls[control.GetId()]);
}
Although that is not ideal because if you send the same control twice, it will only appear once in the map (updated) but twice in the vector of pointers. You can use the returned pait from insert_or_update to fix that:
void AddControl(Control control)
{
auto [iter, was_inserted] = m_controls.insert_or_assign(control.GetId(), control);
// only add to vector if it was not in the map before
if(was_inserted)
m_controlPtrs.push_back(&iter->second);
}
A side note:
It is more idiomatic to return a reference in this situation rather than a pointer:
vector<Control*>& GetControls()
{
return m_controlPtrs;
}
This also breaks encapsulation so it may be worth thinking about how you can avoid accessing the internals of your objects so directly.
Your problem is that you are adding the pointer of a local variable into your m_controlPtrs:
void AddControl(Control control)
{
m_controlPtrs.push_back(&control);
}
Here you take a copy of Control, then add the address of that into your vector. The moment the function returns, your object goes out of scope and that memory is pointing to uninitialised garbage.
You probably want to update AddControl to take a Control&.
#ShadowRanger raises a good point in the comments: what I've mentioned may fix your issue, perhaps indefinitely, but your design still isn't terrific. Any time you have a Control which won't outlive m_controlPtrs you're going to encounter this same problem. Your code is small now, but this may eventually turn into a nightmare to fix. It's likely you should instead update m_controlPtrs to share (or take) ownership of the Control so this problem won't occur.
The easiest way out is to have m_controlPtrs declared as a std::vector<std::shared_ptr<Control>>, but it's something you should think about.

Return a pointer from a function to an object initialized in main()

I have been struggling with this problem for a few hours now and I've searched for every term that made sense to me. I might even have already read through a relevant answer but didn't recognize it as such because I'm a little confused by pointers.
So, I have a struct that is part of an object which is part of a chain of objects that is "anchored" (if you can call it that) in another object, which is itself part of a chain which is "anchored" in an anchor object initialized in main.
struct values
{
double val, ues;
}
class small
{
public:
values vals;
}
class big
{
public:
small *small_anchor;
}
values &getPointerToStruct(big *con)
{
values *return_vals;
if(con->small_anchor->vals.val==10)
return_vals=con->small_anchor->vals;
return (&return_vals);
}
int main()
{
values *main_values=NULL;//This is supposed to be pointing to the "vals" struct contained inside the "small" object.
big *big_anchor;
big_anchor = new big;
big_anchor->small_anchor = new small;
big_anchor->small_anchor->vals.val=10;
big_anchor->small_anchor->vals.ues=5;
main_values = getPointerToStruct(&big_anchor);//now main_values should be pointing to the "vals" struct
//I want to manipulate the value INSIDE the object itself
main_values.val++;
}
I have tried every combination of &, * and no prefix I could come up with, but nothing would give the result I was hoping for. "Closest" I got was copying "vals" (from inside the object) into "main_values" so that I could manipulate the values there, which isn't of any use to me, as I want to manipulate the SOURCE of the variables.
Also please note that I left out the process of scrolling down the chains to get to the object I was trying to reach and that "return_vals" seems arbitrary, but it happens that there are two possible candidates that could be the struct my program is looking for and the "return_vals" contains the best candidate found so far and is overwritten when a better one is found, or returned when the routine ends.
You wrote
values &getPointerToStruct(big *con)
{
values *return_vals;
if(con->small_anchor->vals.val==10)
return_vals=con->small_anchor->vals;
return (&return_vals);
}
where I think you wanted
values *getPointerToStruct(big *con)
{
values *return_vals = 0;
if(con->small_anchor->vals.val==10)
return_vals=&con->small_anchor->vals;
return (return_vals);
}
But the . in main_values.val++; is wrong anyway. You need to be consistent about whether you wanted to work with a values* or a values&. You could make all this work with a values& if you like, but then main_values should be a values& and not declared until you are ready to initialize it. return_vals would not be practical as a values& because of the stated requirement that the full code gives it a tentative address that is conditionally modified later. But even with return_vals as a values* you could still return a values& if that is what you preferred.

Parameter conversion not allowed - MQL5 - CArrayObj

I have the following object declared in my global scope:
CArrayObj *UpwardMovements = new CArrayObj;
And I want to add CUpwards objects to UpwardMovements. CUpwards inherits from CObject so it is possible to add it to the array. However, I cannot add it to the array in a method.
For instance:
void OnTick()
{
CUpwards *UpMovm = new CUpwards(ColorForUpwards);
UpwardMovements.Clear();
CalcUpwardMovement(UpMovm);
}
void CalcUpwardMovement(CUpwards &pUpMovm)
{
UpwardMovements.Add(pUpMovm);
}
I get:
'pUpMovm' - parameter conversion not allowed
If I do the same in my OnTick() method, it works.
Any help would be greatly appreciated.
Using * vs reference. Last line of OnTick(), change to
CalcUpwardMovement(*UpMovm);
Because that method uses reference.
Edit - 4/8
Weird ... does your compiler want another parenthesis? I'm just guessing. I think it should not need another parenthesis.
Your code, with my proposed fix (see "change here" comment)
void OnTick()
{
CUpwards *UpMovm = new CUpwards(ColorForUpwards);
UpwardMovements.Clear();
CalcUpwardMovement( (*UpMovm) ); // change here <<<<<<<<<<<<
}
void CalcUpwardMovement(CUpwards& pUpMovm)
{
UpwardMovements.Add(pUpMovm);
}
Perhaps you did not mean to use the reference (I see you named the formal parameter 'pUpMovm', but a reference is not a pointer. Did you change your mind one place but not the other?
Perhaps you want UpwardMovements.Add(pUpMovm) to be able to modify the local variable pointer UpMovm in OnTick() ... but in this code that would be pointless as the modified pointer would not be used.
I solved the problem as follows:
UpwardMovements.Add(GetPointer(pUpMovm));
You may want to check the pointer before this operation with CheckPointer(GetPointer(pUpMovm));

C++ segfault at the end of a for loop

This code is segfaulting and I can't really figure out why. When I use gdb it segfaults at the end of the function (the curly brace). So that doesn't really give me a lot of information as to what's going on. Here's the code, I'll provide extra info if needed.
typedef std::list<Ground> l_Ground;
void Player::y_collisions(l_Ground grounds) {
for (l_Ground::const_iterator ent = grounds.begin(); ent != grounds.end(); ent++) {
if (getGlobalBounds().intersects(ent->getGlobalBounds())) {
in_air = false;
velocity -= gravity;
}
}
}
EDIT: Upon closer inspection, it's probably segfaulting at the end of that for loop. Which still doesn't really make sense because of the way the for loop is written. It shouldn't go beyond the end of the list.
EDIT2: This will work because of the answer below.
typedef std::list<Ground> l_Ground;
void Player::y_collisions(const l_Ground& grounds) {
for (l_Ground::const_iterator ent = grounds.begin(); ent != grounds.end(); ent++) {
if (getGlobalBounds().intersects(ent->getGlobalBounds())) {
in_air = false;
velocity -= gravity;
}
}
}
You were passing the grounds parameter by value. That means a copy of the list was made. Apparently your Ground class have a broken copy constructor, which makes the getGlobalBounds() method referring to some invalid pointer, which caused the crash.
You should almost never pass a big object by value unless you want to immediately copy it. Always train yourself to type const & all the time :).

Visual Studio Compiler is highlighting Static variables differently?

I'm programming in C++ and have a method which uses a static variable. The method isn't working as I think it should; upon investigation, I found that my static variable is being highlighted in red in two places and blue in other places. Below is the code:
int GameModeState::changeJob(int number)
{
static int job = 1; //red
if (number == 1)
{
job = (job+1); //First one is red, second one is blue
return job; //blue
} else {
return job; //blue
}
}
I'm calling this method with other methods, one shown for example:
int GameModeState::getJob()
{
int currentJob = (changeJob(2));
return currentJob;
}
I want a method like getJob() to simply return the current value of job, while another method, when calling changeJob(number) is changeJob(1), to increment job's value by one. (Hence the if/else statement in changeJob(number)).
Since the job variables are highlighted differently, I'm thinking the compiler is saying that it views the two separately somehow? I'm getting stuck with job being some even value.
EDIT I also have Awesomium... I believe that is the only addition to the compiler, but I'm not completely sure.
MOAR EDIT In another class, I have a method which should determine the current job's number and do something based on if the number is even or odd (since right now there are only two jobs)
void ZoneMovementState::_changeZone(const String& message, const Awesomium::JSValue& input, Awesomium::JSValue& output)
{
//Awesomium::JSValue::Object object = input.getObject();
//String zoneFilename = Convert::toString(object[L"zoneFilename"].toString());
// If the number from getJob is even, the player is currently a geologist
if (GameModeState::getJob()%2 == 0)
{
ZoneParser::getSingleton().load("../media/zones/geology_zone.xml", false);
} else {
ZoneParser::getSingleton().load("../media/zones/farm_zone.xml", false);
}
transitionHandler->go();
}
Ignore the two commented out lines; they deal with JS, which I'm not working on for now.
In the program, I can access the farm_zone until I increment job's value using the below method in GameModeState:
void GameModeState::_openNotebook(const String& message, const Awesomium::JSValue& input, Awesomium::JSValue& output)
{
mNotebookTransition->go();
static int currentJob = changeJob(1);
}
.... So I figured out my problem. While going through the code to show you guys, I realized that the static for currentJob was probably unneeded... once I removed it, my code works as it should now.
Thanks for the help guys!
Part of the problem here is you're using a static local for what very likely should just be a member variable. A static local maintains it's value across all calls to a function in all threads in a process. It's much more likely that you want it to persist for all calls to changeJob in a particular GameModeState instance (else why make it a member functon to begin with?).
To do this you'll need to define a member variable on GameModeState initialize it in the constructor and then access it in the method. For example
class GameModeState {
int job;
GameModeState() : job(1) {}
int changeJob(int number);
};
int GameModeState::changeJob(int number) {
if (number == 1) {
job = (job+1);
return job;
} else {
return job;
}
}
Note: I'm not entirely sure why you're seeing the color's your are seeing. Visual Studio by default won't color member variables a particular color in C++ so it's very likely another add-in you are using.
Nah, highlighting doesn't mean anything. That is, the editor doesn't call the compiler before deciding how/what/when to highlight. So that is not your problem. Sorry 'bout that :-)
You can prove this to yourself by going to Tools->Options->TextEditor and noticing that you can change the highlighting by choosing a different text-editing model.