Error on line -1? - c++

I have a class called PID. I #include the header for the class. I have been using this class in various files including the file the error points to. The compiler complains about defining the function declaration itself void dispPid(char *name, PID &pid){}. All the contents of the function are commented out. The error reads AutoTrucker:-1: error: 'PID' has not been declared with no other errors. Commenting out the function in its entirety removes the error completely, compiles and works fine.
What really gets me confused is that:
The error points to line -1
The file exists, and is included
I use this PID class in right above as a pointer:
PID *pid;
if (chk(arg2,"roll")){pid = &aircraft.ap.pid.wingLeveler;}
else if (chk(arg2,"heading") || chk(arg2,"hdg")){pid = &aircraft.ap.pid.headingHold;}
else if (chk(arg2,"pitch")){pid = &aircraft.ap.pid.pitchHold;}
...
This code specified directly above compiles and works properly. So what gives?
EDIT 2:
This is such a jimmy rig it makes me sick. But is does solve the problem for the time being. So what gives? The compiler does not like the PID class as a function argument, but it finds it acceptable inside the function? I would really like to find a proper solution to this instead of passing in a void pointer and converting it!
void dispPid(const char *name, void *tpid)
{
PID &pid = *((PID*)tpid);
...
}
EDIT: (adding in some more source code as requested)
void cmdsPid(char *buffer)
{
if (chk(buffer,"pid"))
{
char *arg1 = next(buffer);
if (chk(arg1,"ls"))
{
char *arg2 = next(arg1);
if (chk(arg2,"") || chk(arg2,"all"))
{
/*
Serial.println("Listing all PIDs:");
dispPid("Roll",aircraft.ap.pid.wingLeveler);
Serial.print("\t");
dispPid("Heading",aircraft.ap.pid,headingHold);
dispPid("Pitch",aircraft.ap.pid,pitchHold);
Serial.print("\t");
dispPid("V-Rate",aircraft.ap.pid.climbHold);
Serial.print("\t\t");
dispPid("Altitude",aircraft.ap.pid.altHold);
dispPid("Throttle",aircraft.ap.pid.throttleHold);
dispPid("Slip",aircraft.ap.pid.slipHold);
*/
}
else
{
Serial.print("Unknown argument");
}
}
else if (chk(arg1,"w"))
{
char *arg2 = next(arg1);//name
char *arg3 = next(arg2);//attr
char *arg4 = next(arg3);//val
double val = 0.0;
bool onoff = false;
if (chk(arg3,"inv"))
{
onoff = (chk(arg4,"off") || chk(arg4,"-"));
}
else if (chk(arg3,"max") || chk(arg3,"min"))
{
if (chk(arg4,"off") || chk(arg4,"-"))
{
onoff = false;
}
else
{
onoff = true;
val = parseDoubleArg(arg4);
}
}
else
{
val = parseDoubleArg(arg4);
}
PID *pid;
if (chk(arg2,"roll")){pid = &aircraft.ap.pid.wingLeveler;}
else if (chk(arg2,"heading") || chk(arg2,"hdg")){pid = &aircraft.ap.pid.headingHold;}
else if (chk(arg2,"pitch")){pid = &aircraft.ap.pid.pitchHold;}
else if (chk(arg2,"vrate")){pid = &aircraft.ap.pid.climbHold;}
else if (chk(arg2,"alt")){pid = &aircraft.ap.pid.altHold;}
else if (chk(arg2,"th")||chk(arg2,"thr")||chk(arg2,"thro")||chk(arg2,"throttle")){pid = &aircraft.ap.pid.throttleHold;}
else if (chk(arg2,"slip")){pid = &aircraft.ap.pid.slipHold;}
if (chk(arg3,"p")){pid->setPGain(val);}
else if (chk(arg3,"i")){pid->setIGain(val);}
else if (chk(arg4,"d")){pid->setDGain(val);}
else if (chk(arg4,"max"))
{
if (onoff){pid->setLimitMax(val);}
else{pid->disableMaxLimit();}
}
else if (chk(arg4,"min"))
{
if (onoff){pid->setLimitMin(val);}
else{pid->disableMinLimit();}
}
}
else
{
Serial.println("Unknown argument");
}
}
}
void dispPid(char *name, PID &pid){}
The PID class (header):
#pragma once
#define PID_VERSION "1.1"
#include <inttypes.h>
#define allowLimitMax 1
#define allowLimitMin 2
#define invert 4
#define enabled 8
class PID
{
private:
double pGain,iGain,dGain;
double integrator;
double *input,*output,*setpoint;
double lastInput;
double limitMax,limitMin;
char settings;
public:
struct Spid {
double p,i,d,limitMax,limitMin;
char settings;
};
PID();//constructor
//getters
double getPGain();
double getIGain();
double getDGain();
double getLimitMax();
double getLimitMin();
bool isLimitMaxSet();
bool isLimitMinSet();
bool isInverted();
//setters
void setPGain(double newPGain);
void setIGain(double newIGain);
void setDGain(double newDGain);
void setPIDGain(double newPGain, double newIGain, double newDGain);
void setInput(double *newInput);
void setOutput(double *newOutput);
void setSetpoint(double *newSetpoint);
void setIOS(double *newInput, double *newOutput, double *newSetpoint);
void setLimitMax(double newLimitMax);
void setLimitMin(double newLimitMin);
void setLimits(double newLimitMin, double newLimitMax);
void disableMaxLimit();
void disableMinLimit();
void disableLimits();
void zeroOutIntegrator();
void nullOut();
void setInverted(bool newInvert);
//actions
void run();
void run(double dt);
void setFrom(Spid copy);
void copy(Spid &copy);
};

Related

C++ & Esp8266 LoadStoreAlignmentCause with pointer

I am trying to access a function of a pointer and it does not work and it gives me an LoadStoreAlignmentCause Exception. Furthermore I want to check if the pointer does exist, but it always returns true for that.
LedFunction.h
#include "Led/LedStates.h"
class LedStates;
class LedFunction {
public:
LedStates *state;
virtual bool init();
bool loadValues();
virtual void render() = 0;
};
LedFunction.cpp
#include "Led/LedFunction.h"
bool LedFunction::init() {
return false;
}
RainbowFunction.h
class RainbowFunction: public LedFunction {
public:
RainbowFunction() {
Serial.println("Rainbow Constructor.");
}
void render() {
Serial.println("From Rainbow...");
}
}
};
LedStates.h
#include "Handlers/LedHandler.h"
#include "Led/LedFunction.h"
class LedHandler;
class LedFunction;
class LedStates {
public:
uint8_t (*values)[3];
int count = 0;
bool dirty = false;
LedHandler* ledHandler;
LedFunction* function = 0;
LedStates(LedHandler* handler);
void setFunction(LedFunction *newFunction);
void setRgb(int i, uint8_t r, uint8_t g, uint8_t b);
void render(); //TODO check virtual key
void setValues(LedStates &to);
void commit();
void fade(LedStates &to, long f0, long f1);
};
LedStates.cpp
#include "Led/LedStates.h"
#include "Led/Animations/RainbowFunction.h"
LedStates::LedStates(LedHandler* handler) {
this->ledHandler = handler;
count = ledHandler->getLength();
values = new uint8_t[count][3];
this->setFunction(new RainbowFunction());
}
void LedStates::setFunction(LedFunction* newFunction) {
Serial.println("SETTING FUNCTION");
if(function)
delete function; //TODO check virtual destructor
function = newFunction;
if(!function)
return;
function->state = this;
Serial.println("-----Setting Done-----");
}
void LedStates::render() {
Serial.println(2);
Serial.println("B:" + (String) (function != 0));
Serial.println("B:" + (String) (function != false));
if(function == nullptr) { //This is the check that is not working properly
Serial.println(22222);
//delay(1000);
//function->render();
} else {
Serial.println(33333);
function->render();
}
Serial.println(3);
}
LedHandler.h
#include <Arduino.h>
#include <Adafruit_NeoPixel.h>
#include <FastLED.h>
//#include "Led/LedFunction.h"
#include "Led/LedStates.h"
#include "Led/Fading.h"
class LedStates;
class LedHandler {
public:
LedHandler(int length, uint16_t pin);
void clear();
void show();
void setColor(int s, int r, int g, int b);
void loop();
Adafruit_NeoPixel getStrip();
int getLength();
private:
LedStates* currentState;
LedStates* targetState;
Fader<LedStates> *ledFader;
int length;
Adafruit_NeoPixel strip;
CRGB* leds;
};
LedHandler.cpp
#include "Handlers/LedHandler.h"
LedHandler::LedHandler(int length, uint16_t pin) {
Serial.begin(115200);
this->length = length;
this->strip = Adafruit_NeoPixel(length, pin);
this->strip.begin();
CRGB* arr = new CRGB[length];
this->leds = arr;
FastLED.addLeds<WS2812B, 6, RGB>(leds, 60).setCorrection(TypicalLEDStrip);
//Serial.println("-----Creating States-----");
LedStates currentLedStates = LedStates(this);
LedStates targetLedStates = LedStates(this);
Fader<LedStates> ledFader = Fader<LedStates>(currentLedStates, targetLedStates);
//Serial.println("-----Created States-----");
this->currentState = &currentLedStates;
this->targetState = &targetLedStates;
this->ledFader = &ledFader;
}
void LedHandler::loop() {
Serial.println("--::--::--::--::--::--::--");
currentState->render();
Serial.println(99);
Serial.println(6);
currentState->commit();
Serial.println("-------------------------");
delay(10000);
}
The Serialmonitor output:
SETTING FUNCTION
-----Setting Done-----
Rainbow Constructor.
SETTING FUNCTION
-----Setting Done-----
--::--::--::--::--::--::--
2
B:1
B:1
33333
Exception (9):
epc1=0x40202a92 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4020d32d depc=0x00000000
These lines define local variables inside the function LedHandler::LedHandler(int length, uint16_t pin):
LedStates currentLedStates = LedStates(this);
LedStates targetLedStates = LedStates(this);
These lines remember the address of the local variables:
this->currentState = &currentLedStates;
this->targetState = &targetLedStates;
This line deletes the local variables so the memory can be used for something else:
}
and this line calls the something else (nobody knows what it will be):
currentState->render();

'Read access violation' exception in an SFML/C++ project:

I'm recently learning to make a 2d game in SFML using a tutorial series on youtube by Suraj Sharma(Video 57):
https://www.youtube.com/watch?v=kwd_AVCkvXE&list=PL6xSOsbVA1ebkU66okpi-KViAO8_9DJKg&index=57
His Source Code:
https://github.com/Headturna/SFML_RPG
Right now he's teaching me to symplify the game's menu system by making a mini class 'StateData' in the parent class 'State' so any inherited class can access 'State' parameters via 'StateData'(Ex:MainMenu(StData* Stdata){}).
After debugging the game seems to runs fine.But everytime i click on something on the menu(start,settings,etc...) a 'Read access violation:Stdata was nullptr' occurs in the 'State' class constructor.
Here's the code:
State.h:
#pragma once
#ifndef STATE_H
#define STATE_H
#include "Player.h"
#include "GrphSettings.h"
class Player;
class GrphSettings;
class State;
class StData {
public:
StData(){}
//Vars
float GridSize;
sf::RenderWindow* Window;
GrphSettings* GSettings;
std::map<std::string, int>* SupportedKeys;
std::stack<State*>* states;
};
class State
{
private:
protected:
StData* Stdata;
std::stack<State*>* states;
sf::RenderWindow* window;
std::map<std::string, int>* SupportedKeys ;
std::map<std::string, int> Keybinds;
bool quit;
bool pause;
float keyTime;
float keyTimeMax;
float GridSize;
sf::Vector2i MousePosScr;
sf::Vector2i MousePosWind;
sf::Vector2f MousePosView;
//Resources
std::map<std::string,sf::Texture> texture;
//Funcs
virtual void InitKeybinds() = 0;
public:
State(StData* Stdata);
virtual~State();
//Access
const bool getKeytime();
const bool& getquit()const;
//Funcs
void Endstate();
void PauseSt();
void UnPauseSt();
virtual void UpdateInput(const float& dt) = 0;
virtual void UpdateMousePos();
virtual void UpdateKeyTime(const float& dt);
virtual void Update(const float& dt) = 0;
virtual void Render(sf::RenderTarget* target = nullptr) = 0;
};
#endif // !1
State.cpp:
#include "pch.h"
#include "State.h"
State::State(StData* Stdata)
{
this->Stdata = Stdata;
this->window = Stdata->Window;
this->SupportedKeys = Stdata->SupportedKeys;
this->states = Stdata->states;
this->quit = false;
this->pause = false;
this->keyTime = 0.f;
this->keyTimeMax = 10.f;
this->GridSize = Stdata->GridSize;
}
State::~State()
{
}
//Access
const bool State::getKeytime()
{
if (this->keyTime >= this->keyTimeMax) {
this->keyTime = 0.f;
return true;
}
return false;
}
const bool& State::getquit() const
{
// TODO: insert return statement here
return this->quit;
}
//Funcs
void State::Endstate()
{
this->quit = true;
}
void State::PauseSt()
{
this->pause = true;
}
void State::UnPauseSt()
{
this->pause = false;
}
void State::UpdateMousePos()
{
this->MousePosScr = sf::Mouse::getPosition();
this->MousePosWind = sf::Mouse::getPosition(*this->window);
this->MousePosView = this->window->mapPixelToCoords(sf::Mouse::getPosition(*this->window));
}
void State::UpdateKeyTime(const float& dt)
{
if (this->keyTime < this->keyTimeMax)
this->keyTime += 100.f * dt;
}
Every button one the menu(start,exit...)is an inherited state from 'State' class.This is,for example,the 'Edit' state.
Edit.h:
#pragma once
#ifndef EDIT_H
#define EDIT_H
#include "State.h"
#include "Gui.h"
#include "PauseMenu.h"
#include "TileMap.h"
class State;
class Gui;
class PauseMenu;
class TileMap;
class Edit:public State
{
private:
//Vars
sf::Font Fnt;
PauseMenu* PMenu;
std::map<std::string, gui::Button*> buttons;
TileMap Map;
//Functions
void InitVars();
void InitBackGrnd();
void InitFonts();
void InitKeybinds();
void InitPauseMenu();
void InitBtn();
public:
Edit(StData* Stdata);
virtual~Edit();
//Functions
void UpdateInput(const float& dt);
void Update(const float& dt);
void UpdatePButtons();
void UpdateBtn();
void Endstate();
void RenderBtn(sf::RenderTarget& target);
void Render(sf::RenderTarget* target = nullptr);
};
#endif // ! EDIT_H
Edit.cpp:
#include "pch.h"
#include "Edit.h"
void Edit::InitVars()
{
}
void Edit::InitBackGrnd()
{
}
void Edit::InitFonts()
{
if (!this->Fnt.loadFromFile("Fonts/SPACEMAN.ttf")) {
throw("Error::Edit::Couldn't load font");
}
}
void Edit::InitKeybinds()
{
std::ifstream ifs("Config/EditKeys.ini");
if (ifs.is_open()) {
std::string key = "";
std::string key2 = "";
int keyval = 0;
while (ifs >> key >> key2)
{
this->Keybinds[key] = this->SupportedKeys->at(key2);
}
}
ifs.close();
this->Keybinds["Close"] = this->SupportedKeys->at("ESC");
this->Keybinds["Left"] = this->SupportedKeys->at("A");
this->Keybinds["Right"] = this->SupportedKeys->at("D");
this->Keybinds["Up"] = this->SupportedKeys->at("W");
this->Keybinds["Down"] = this->SupportedKeys->at("S");
}
void Edit::InitPauseMenu()
{
this->PMenu = new PauseMenu(*this->window, this->Fnt);
this->PMenu->addButtons("Quit", 800.f, "Quit");
}
void Edit::InitBtn()
{
}
Edit::Edit(StData* Stdata)
:State(Stdata)
{
this->InitVars();
this->InitBackGrnd();
this->InitFonts();
this->InitKeybinds();
this->InitPauseMenu();
this->InitBtn();
}
Edit::~Edit()
{
auto it = this->buttons.begin();
for (it = this->buttons.begin(); it != this->buttons.end(); ++it) {
delete it->second;
}
delete this->PMenu;
}
//Funcs
void Edit::UpdateInput(const float& dt)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key(this->Keybinds.at("Close")))
&& this->getKeytime()) {
if (!this->pause)
this->PauseSt();
else this->UnPauseSt();
}
}
void Edit::Update(const float& dt)
{
this->UpdateMousePos();
this->UpdateKeyTime(dt);
this->UpdateInput(dt);
if (!this->pause) {//Unpaused
this->UpdateBtn();
}
else {//Paused
this->PMenu->Update(this->MousePosView);
this->UpdatePButtons();
}
this->UpdateBtn();
std::cout << this->MousePosView.x << " " << this->MousePosView.y << "\r";
}
void Edit::UpdatePButtons()
{
if (this->PMenu->isPressed("Quit"))
this->Endstate();
}
void Edit::UpdateBtn()
{ //Update buttons and handle their functions
for (auto& it : this->buttons) {
it.second->Update(MousePosView);
}
}
void Edit::Endstate()
{
std::cout << "Ending State" << "\n";
}
void Edit::RenderBtn(sf::RenderTarget& target)
{
for (auto& it : this->buttons) {
it.second->Render(target);
}
}
void Edit::Render(sf::RenderTarget* target)
{
if (!target)
target = this->window;
this->RenderBtn(*target);
this->Map.Render(*target);
if (this->pause) {//Pause Menu
this->PMenu->Render(*target);
}
sf::Text MText;
MText.setPosition(this->MousePosView);
MText.setFont(this->Fnt);
MText.setCharacterSize(12);
std::stringstream ss;
ss << this->MousePosView.x << ' ' << this->MousePosView.y;
MText.setString(ss.str());
target->draw(MText);
}
Can anyone help me ?

qualified-id in declaration before '=' token / object counter variable

I'm trying to count how many instances or the class mole2 there are and store the number in a public static variable called mole_count.
mole2.h
#ifndef mole2_h
#define mole2_h
#include "Arduino.h"
class mole2 {
public:
mole2(int input, int output);
void popUp();
void popdown();
boolean moleBrainThinkPopUpNow();
void setUpTimer(int up_timer);
boolean didMoleGetHit();
void setRecoveryTimer(int recovery_timer);
void decrementRecoveryTimer();
boolean dosePlayerMistMole();
void moleReset();
int input, output;
static int mole_count;
static int odds_of_poping;
private:
boolean _is_popped = false;
int _up_timer = 0;
int _recovery_timer = 0;
};
#endif
mole2.cpp
#include "Arduino.h"
#include "mole2.h"
int mole2::odds_of_poping = 10;
mole2::mole2(int input, int output) {
input = input;
output = output;
int mole2::mole_count = mole2::mole_count + 1;
pinMode(input, INPUT);
pinMode(output, OUTPUT);
}
void mole2::popUp() {
_is_popped = true;
digitalWrite(input, HIGH);
}
void mole2::popdown() {
_is_popped = false;
digitalWrite(input, LOW);
}
boolean mole2::moleBrainThinkPopUpNow() {
if (_recovery_timer == 0 && _is_popped == false && rand() % odds_of_poping == 1) {
popUp();
return true;
}
else {
return false;
}
}
void mole2::setUpTimer(int up_timer) {
_up_timer = up_timer;
}
boolean mole2::didMoleGetHit() {
if (_is_popped == true && digitalRead(input) == HIGH) {
popdown();
_up_timer = 0;
return true;
}
else {
return false;
}
}
void mole2::setRecoveryTimer(int recovery_timer) {
_recovery_timer = recovery_timer;
}
void mole2::decrementRecoveryTimer() {
if (_recovery_timer > 0) {
_recovery_timer--;
}
}
boolean mole2::dosePlayerMistMole() {
if (_is_popped == true && _up_timer > 0) {
_up_timer--;
}
if (_is_popped == true && _up_timer == 0) {
popdown();
return true;
}
else {
return false;
}
}
void mole2::moleReset() {
popdown();
_up_timer = 0;
_recovery_timer = 0;
}
FullError
Arduino: 1.6.12 (Windows 7), Board: "Arduino/Genuino Uno"
C:\Users\Strings\Documents\Arduino\libraries\mole2\mole2.cpp: In constructor 'mole2::mole2(int, int)':
C:\Users\Strings\Documents\Arduino\libraries\mole2\mole2.cpp:9:25: error: qualified-id in declaration before '=' token
int mole2::mole_count = mole2::mole_count + 1;
^
exit status 1
Error compiling for board Arduino/Genuino Uno.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
First this:
int mole2::mole_count = mole2::mole_count + 1;
has no sense: you're declaring something and assigning it to its value + 1
Anyway, you already declared mole_count in your class. Since you're in the constructor, you're in the mole2 class already (the "qualified-id" bit comes from here), so you just have to do:
mole_count++;
Also, you have to declare storage for the variable in the .cpp class & initialize it:
int mole2::mole_count = 0;
You have to do the same thing as with odds_of_poping:
Definition:
int mole2::mole_count = 0; // initialization can be ommited as static variables are initialized to the default value
and later just increment: ++mole_count;
int mole2::mole_count has already been defined. This is trying to make another int mole2::mole_count. Lose the int and assign to the pre-existing variable.
You also need to allocate storage for and initialize mole_count. Place
int mole2::mole_count = 0; // replace 0 if starting with more than 0 mole2s
in somewhere around
int mole2::odds_of_poping = 10;
in mole2.cpp
Also watch out for
input = input;
output = output;
The compiler doesn't know whether you want to use the passed parameter input or the class's input so it will pick the closest defined input, the parameter, on both sides of the = . Refrain from reusing the same variable names in the same places at the same times.
This can be resolved by explicitely stating
this->input = input;
this->output = output;
Or (my favourite!) by using the member initializer list
mole2::mole2(int input, int output): input(input), output(output) {
But to prevent other confusion you should still not repeat the names.

Function returning function pointer from table as a parameter

I have been reading for a while, but today I can't figure someting out and find a solution.
How to return a function pointer from a function table as parameter? All similair solutions don't work for this one and end up not compiling.
I have tried a lot of methods but the compiler always returns with errors like:
function returning function is not allowed solution (when using typedef void (*func)();)
As NO parameters have to be passed into the final routine it should be possible.
My simplified example:
void PrintOne(void) { printf("One")};
void PrintTwo(void) { printf("Two")};
struct ScanListStruct
{
int Value;
void (*Routine)(void);
}
const ScanListStruct DoList[] =
{
{1, PrintOne},
{2, PrintTwo}
}
bool GetRoutine(void *Ptr, int Nr)
{
for (int x =0; x<=1; x++)
{
if (DoList[x].Value = Nr)
{
Ptr = DoList[(x)].Routine;
//((*DoList[(x)].Routine)()); // Original Working and executing version!
return true;
}
}
return false;
}
void main(void)
{
int y = 1;
void (*RoutineInMain)(); // Define
if (GetRoutine( RoutineInMain, y) == true) // get the address
{
RoutineInMain(); // Execute the function
}
}
There a few things wrong with the code;
Syntax errors (missing ; etc.)
main must return int
GetRoutine should accept the function pointer by reference, not just a void* pointer to anything
if condition should contain an equality test, not an assignment
As follows, works as expected;
void PrintOne(void) { printf("One"); };
void PrintTwo(void) { printf("Two"); };
struct ScanListStruct
{
int Value;
void (*Routine)(void);
};
const ScanListStruct DoList[] =
{
{1, &PrintOne},
{2, &PrintTwo}
};
bool GetRoutine(void (*&Ptr)(), int Nr)
{
for (int x =0; x<=1; x++)
{
if (DoList[x].Value == Nr)
{
Ptr = *DoList[(x)].Routine;
//((*DoList[(x)].Routine)()); // Original Working and executing version!
return true;
}
}
return false;
}
int main(void)
{
int y = 1;
void (*RoutineInMain)(); // Define
if (GetRoutine( RoutineInMain, y) == true) // get the address
{
RoutineInMain(); // Execute the function
}
}
Prints One.
You have lots of errors in your code. Like here you put the comas at the wrong place:
void PrintOne(void) { printf("One")};
void PrintTwo(void) { printf("Two")};
It should be
void PrintOne(void) { printf("One");}
void PrintTwo(void) { printf("Two");}
And here you are using the wrong operator, = instead of ==.
if (DoList[x].Value = Nr)
When the argument Ptr is a pointer, and that is passed by value, so the value assigned in the function will not be available when the function returns.
This is how your code should be:
void PrintOne(void) { printf("One"); }
void PrintTwo(void) { printf("Two"); }
typedef void(*prototype)();
struct ScanListStruct
{
int Value;
prototype Routine;
};
const ScanListStruct DoList[] =
{
{ 1, PrintOne },
{ 2, PrintTwo }
};
bool GetRoutine(prototype &Ptr, int Nr)
{
for (int x = 0; x <= 1; x++)
{
if (DoList[x].Value == Nr)
{
Ptr = DoList[(x)].Routine;
return true;
}
}
return false;
}
int main()
{
int y = 1;
prototype RoutineInMain; // Define
if (GetRoutine(RoutineInMain, y) == true) // get the address
{
RoutineInMain(); // Execute the function
}
return 0;
}

New command not making a new object C++

I will start by explaining my issue, and then provide a good portion of the code.
I and filling a queue with a custom class called process. Using this line:
ProcessQueue.push(new Process(inputs[0], inputs[1], inputs[2], inputs[3], inputs[4]));
This all seems well and good, when the loop is done Process queue is filled with pointers.
However upon further inspection I found out they all point to the SAME object?
Finding this curious, I stepped into the constructor on each iteration of the loop.
First iteration: when the constructor is entered all instance variables are null (as expected)
Second iteration: upon entering the constructor, all instance variables contain the values given to the object in the first iteration (ie: the same object)
Furthermore later when I use the queue I have confirmed that every pointer in the queue is referring to the same process object. (I can tell this because process contains a state and if loop through the queue changing the state, I will find the state already changed for the second pointer)
I suspect I must have done something wrong with the creation of me class. so here it is in its entirety.
Process.h
#pragma once
class Process
{
public:
Process(int _processId, int _arrivalTime, int _CPUTime,
int _IOFrequency, int _IODuration);
~Process();
bool HasArrived(int time);
bool HasCompleted();
bool HasFinishedBurst();
bool HasFinishedIO();
int GetQueueNum();
int GetID();
void SetQueueNum(int i);
void SetToReady();
void Run();
void PerformIO();
};
Process.cpp
#include "stdafx.h"
#include "Process.h"
#include <string>
using namespace std;
int processId;
int arrivalTime;
int CPUTime;
int IOFrequency;
int IODuration;
int Ticks;
int CPUConsumption;
int CPUBurstSize;
int queueNumber;
int IOBurstCount;
string state;
Process::Process(int _processId, int _arrivalTime, int _CPUTime,
int _IOFrequency, int _IODuration)
{
processId = _processId;
arrivalTime = _arrivalTime;
CPUTime = _CPUTime;
IOFrequency = _IOFrequency;
IODuration = _IODuration;
IOBurstCount = 0;
CPUConsumption = 0;
Ticks = 0;
queueNumber = 0;
state = "None";
printf("%d: %s\n", processId,state.c_str());
int excess = CPUTime % IOFrequency;
if (excess == 0)
{
CPUBurstSize = CPUTime / IOFrequency;
}
else
{
CPUBurstSize = (CPUTime - excess) / (IOFrequency - 1);
}
}
Process::~Process()
{
}
bool Process::HasArrived(int time)
{
if (arrivalTime <= time)
{
if (state.compare("Newly Arrived") == 0)
{
printf("Already arrived!\n");
}
state = "Newly Arrived";
printf("%d: %s\n", processId, state.c_str());
return true;
}
else
{
return false;
}
}
bool Process::HasCompleted()
{
if (CPUConsumption == CPUTime && IOBurstCount == IOFrequency)
{
state = "Finished";
printf("%d: %s\n", processId, state.c_str());
return true;
}
else
{
return false;
}
}
bool Process::HasFinishedBurst()
{
if (Ticks == CPUBurstSize)
{
Ticks = 0;
state = "Blocked";
printf("%d: %s\n", processId, state.c_str());
return true;
}
else
{
return false;
}
}
bool Process::HasFinishedIO()
{
if (Ticks >= IODuration)
{
IOBurstCount++;
Ticks = 0;
return true;
}
else
{
return false;
}
}
void Process::SetToReady()
{
state = "Ready";
printf("%d: %s\n", processId, state.c_str());
}
void Process::Run()
{
state = "Running";
printf("%d: %s\n", processId, state.c_str());
Ticks++;
CPUConsumption++;
}
void Process::PerformIO()
{
Ticks++;
}
int Process::GetQueueNum()
{
return queueNumber;
}
void Process::SetQueueNum(int i)
{
queueNumber = i;
}
int Process::GetID()
{
return processId;
}
I suspect I have somehow created this as a static class without meaning too...
It seems you have placed all your member variables outside the class!
int processId;
int arrivalTime;
int CPUTime;
int IOFrequency;
int IODuration;
int Ticks;
int CPUConsumption;
int CPUBurstSize;
int queueNumber;
int IOBurstCount;
string state;
Should be here:
class Process
{
public:
Process(int _processId, int _arrivalTime, int _CPUTime,
int _IOFrequency, int _IODuration);
~Process();
bool HasArrived(int time);
bool HasCompleted();
bool HasFinishedBurst();
bool HasFinishedIO();
int GetQueueNum();
int GetID();
void SetQueueNum(int i);
void SetToReady();
void Run();
void PerformIO();
private:
int processId;
int arrivalTime;
int CPUTime;
int IOFrequency;
int IODuration;
int Ticks;
int CPUConsumption;
int CPUBurstSize;
int queueNumber;
int IOBurstCount;
string state;
};
You defined global variables
int processId;
int arrivalTime;
int CPUTime;
int IOFrequency;
int IODuration;
and the constructor of class Process each time when it is called overrides their values.
Process::Process(int _processId, int _arrivalTime, int _CPUTime,
int _IOFrequency, int _IODuration)
{
processId = _processId;
arrivalTime = _arrivalTime;
CPUTime = _CPUTime;
IOFrequency = _IOFrequency;
IODuration = _IODuration;
IOBurstCount = 0;
CPUConsumption = 0;
Ticks = 0;
queueNumber = 0;
//...
While the class itself has no data members.
So these global variables keep that values that were assigned to them in the last call of the constructor.