There is a problem in the simple code snippet below that i can't uncover even with a debugger. Thanks for your help in advance.
Command.h
class word{
private : static int next_word;
private : int word_id;
public : word();
public : void grabIt();
public : void raiseIt();
public : void putItDown();
};
class Command{
public : typedef void(word::*Method)();
private : word* w;
private : Method m;
public : Command(word *w, Method m);
public : void execute();
};
template<typename T>
class Queue{
private : enum{
SIZE=9
};
private : T* commandArray[SIZE];
private : int m_added = 0, m_removed = 0;
public : void enqueue(T* t){
commandArray[m_added] = t;
m_added = (m_added + 1) % SIZE;
}
public : T* dequeue(){
int temp = m_removed;
m_removed = (m_removed + 1) % SIZE;
return commandArray[temp];
}
};
Command.cpp
int word::next_word = 0;
word::word(){
this->word_id = next_word++;
}
void word::grabIt(){
std::cout << "Grabbed it" << std::endl;
}
void word::raiseIt(){
std::cout << "Raised it" << std::endl;
}
void word::putItDown(){
std::cout << "Put it down" << std::endl;
}
Command::Command(word *w, Method m){
w = w;
m = m;
}
void Command::execute(){
(w->*m)(); // -------------->>>>> Causing Seg-Fault
}
Main.cpp
Queue<Command> queue;
Command *commandArray[9];
Command command1(new word, &word::grabIt); commandArray[0] = &command1;
Command command2(new word, &word::raiseIt); commandArray[1] = &command2;
Command command3(new word, &word::putItDown); commandArray[2] = &command3;
Command command4(new word, &word::grabIt); commandArray[3] = &command4;
Command command5(new word, &word::raiseIt); commandArray[4] = &command5;
Command command6(new word, &word::putItDown); commandArray[5] = &command6;
Command command7(new word, &word::grabIt); commandArray[6] = &command7;
Command command8(new word, &word::raiseIt); commandArray[7] = &command8;
Command command9(new word, &word::putItDown); commandArray[8] = &command9;
for( int i=0 ; i < 9; i++){
queue.enqueue(commandArray[i]);
}
for( int i=2 ; i < 6 ; i++){
queue.dequeue()->execute();
}
Some word objects inside the queue appear NULL in the debugger, so cause Seg-Fault.
To fix the problem, change
Command::Command(word *w, Method m){
w = w;
m = m;
}
to
Command::Command(word *w, Method m) : w(w), m(m){}
For the exact reasoning, look at Can I use identical names for fields and constructor parameters?
Related
I keep getting this error that only virtual functions can be marked as override but the functions in question "norm()" and "string to_string()" are virtual. what could be causing this?
In my main function I am also getting the error no matching member function to call push back, did I make a mistake along the way somewhere and I am just not seeing it?
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
class Group
{
public:
virtual string to_string() = 0;
virtual int norm() = 0;
};
class Real
{
// add your code here
protected:
int number;
public:
Real(int num)
{
number = num;
}
int norm() override
{
return number;
}
string to_string() override
{
return number;
}
int getNumber() const
{
return number;
}
void setNumber(int number)
{
Real::number = number;
}
};
class Complex : public Real
{
// add your code here
protected:
int imaginary;
public:
Complex(int realNum, int imag) : Real(realNum)
{}
int norm() override
{
return sqrt(number * number + imaginary * imaginary) + 'i';
}
string to_string() override
{
return ::to_string(number) + '+' + ::to_string(imaginary) + 'i';
}
};
class Trinomial : public Complex
{
// add your code here
protected:
int third;
public:
Trinomial(int p1, int p2, int p3) : Complex(p1, p2) {
third = p3;
}
int norm() override {
return sqrt(number * number + imaginary * imaginary + third * third);
}
string to_string() override {
return ::to_string(number) + "x^2+" + ::to_string(imaginary) + "x+" + ::to_string(third);
}
};
class Vector : public Group
{
// add your code here
protected:
vector<int> v;
public:
Vector(int num1, int num2, int num3)
{
v.push_back(num1);
v.push_back(num2);
v.push_back(num3);
}
int norm() override
{
int squared_sum = 0;
for (int i = 0; i < v.size(); i++) {
squared_sum += v[i] * v[i];
}
return sqrt(squared_sum);
}
string to_string() override
{
string str = "[";
for (int i = 0; i < v.size() - 1; i++) {
str += ::to_string(v[i]) + " ";
}
str += ::to_string(v[v.size() - 1]) + "]";
return str;
}
};
int main()
{
vector<Group*> elements;
elements.push_back(new Real{ 3 });
elements.push_back(new Complex{ 3,4 });
elements.push_back(new Trinomial{ 1,2,3 });
elements.push_back(new Vector{ 1,2,3 });
for (auto e : elements)
{
cout << "|" << e->to_string() << "| = " << e->norm() << endl;
}
for (auto e : elements)
delete e;
return 0;
}
A couple of issues here:
The class Real must have inherited from Group so that you could override the functions. That is the reason for the error message.
Secondly the Real::to_string must return a string at the end. You
might convert the integer using std::to_string.
Last but not least the Group must have a virtual destructor for defined behaviour. Read more here: When to use virtual destructors?
In short, you need
#include <string>
class Group
{
public:
// other code
virtual ~Group() = default;
};
class Real: public Group // --> inherited from base
{
// other codes
public:
std::string to_string() override {
return std::to_string(number);
}
};
As a side, please do not practice with using namespace std;
your class real has no parent. so you cant override to_string()
I'd like to access to a double pointer which is located in another class "Board".
class Board
{
public:
Board(void);
Board(unsigned int xSize, unsigned int ySize);
~Board(void);
void SetObjectManager(ObjectManager* pObm);
void SetBlock(Block* block);
void LoadBoard(void);
void InitBoard(void);
//Other Functions...
private:
ObjectManager* m_obm;
Block* m_block;
//pointer to pointer to a int. (for 2 dimensional-array)
int **m_board;
};
First, the Board class. at the last line of class, you can see m_board.
I want to change this value in outside of this class.
Like this,
void Block::InitBlock(void)
{
int randPiece = Random::GIRand().RandInt(0, 1);
int randPos = Random::GIRand().RandInt(0, 10);
switch (randPiece)
{
case 0:
m_piece[2][1] = 1;
m_piece[2][2] = 1;
m_piece[2][3] = 1;
m_piece[3][3] = 1;
break;
//Other cases are here...
}
std::cout << "RandPos : " << randPos << std::endl;
std::cout << "RandPiece : " << randPiece << std::endl;
for (int y = 0; y < m_ySize; ++y)
{
for (int x = 0, pX = randPos; x < m_xSize; ++x, ++randPos)
{
if (m_piece[x][y] != 0)
m_board->SetBoardStatus(randPos, y, 1);
}
}
}
But, When I run this program, It blows up at SetBoardStatus(int, int, int)
SetBoardStatus looks like this,
void Board::SetBoardStatus(int x, int y, int value)
{
m_board[x][y] = value; //Visual Studio breaks the program here.
}
I allocate the double pointer properly.
And I set the board at the outside of this classes.
void Block::SetBoard(Board* board)
{
m_board = board;
}
And this is my block class.
class Block
{
public:
Block(void);
~Block(void);
void SetObjectManager(ObjectManager* pObm);
void LoadBlock (void);
void InitBlock (void);
void UpdateBlock (void);
void ReleaseBlock (void);
void SetBoard(Board* board);
private:
ObjectManager* m_obm;
Board* m_board;
int **m_piece;
int m_xSize;
int m_ySize;
};
Consider inheriting Block in Board; This will eliminate any possible de-referencing errors or bugs, as you can access the pointer right away.
I'm writing a somewhat toy program to get into c++. However I'm having quite a lot of trouble with a segmentation fault at a very specific line in my code. I know that the segmentation fault means I tried to access memort that was not given to my program.
The code is (somewhat) as follows(it's actually too big to just copy paste) :
class car {
protected:
int speed;
std::string brand;
public:
car (int s, std::string b):speed(s),brand(b) {
std::cout << "New car has been created" << endl;
}
virtual int is_stopped () {
if (speed==0) return 1;
else return 0;
}
virtual void speed_up () {
speed++;
}
car* clone () {
car* tmp(this);
return tmp;
}
};
class fast_car : public car {
public:
fast_car (int s, std::string b):car(s,b) { }
};
class slow_car : public car {
public:
slow_car (int s, std::string b):car(s,b) { }
};
class highway {
int number_of_cars;
car **first; //There are derived classes from car hence the double pointer
public:
highway (int c, int s, std::string b):number_of_cars(c) {
first = new car*[c];
for (int i=0;i<c/2;i++)
first[i] = new fast_car (s,b);
for (int i=c/2;i<c;i++)
first[i] = new slow_car (s,b);
}
void speed_up () {
int pos;
pos = rand()%number_of_cars; //give me a random number between 0 and number_of_cars;
if (pos!=0) pos--; //We don't want position -1
first[pos]->speed_up ();
clone_fast (first[pos], (number_of_cars - pos - 1)); //the second argument is the remaining array "spots" until the end of the array
}
void clone_fast (car* cur, int rem) {
car* tmp;
for (int i=-;i<=rem;i++)
if ((cur+1)->is_stopped ()) { //Exact line where I get the segmentation fault
tmp = cur->clone ();
cur++;
}
}
};
So there it is. I tried to give you everything I could to recreate the problem. I'll try to solve any further questions.
Any help would be greatly appreciated.
The car*s are created by new, and aren't necessarily contiguous; they certainly aren't arrays that you can pointer-arithmetic around with. (car*) + 1 is not the same as (car**)[i + 1] (which is more like (car**) + 1). You probably want something a bit more like (*(first + 1))->doThing(), not (first[X] + 1)->doThing().
Edit: to be a bit more clear, if you can't do car[X + 1], then you can't do *(car + 1). Since the cars in clone_fast() are object pointers and not arrays, you can't do car[X + 1], thus (cur + 1)->is_stopped() is wrong.
I would suggest removing all pointer crap, and use more modern idioms. You can expand on the code below. However, it is unclear to me why you have two derived classes: they have no specific data neither methods, so why ?
class car
{
private:
int speed;
std::string brand;
public:
car (int s, std::string b):speed(s),brand(b)
{
std::cout << "New car has been created" << endl;
}
bool is_stopped ()
{
return speed==0;
}
void speed_up ()
{
speed++;
}
};
class fast_car : public car
{
public:
fast_car (int s, std::string b):car(s,b) {}
};
class slow_car : public car
{
public:
slow_car (int s, std::string b):car(s,b) {}
};
class highway
{
private:
std::vector<std::shared_ptr<car>> v_cars;
public:
highway (int c, int s, std::string b):number_of_cars(c)
{
for (int i=0;i<c/2;i++)
v_cars.push_back( std::make_shared<fast_car>(s,b) );
for (int i=c/2;i<c;i++)
v_cars.push_back( std::make_shared<slow_car>(s,b) );
}
};
int main()
{
highway h( 50, 20 );
return 0;
}
I think the best way to explain my question is with a piece of code:
class IncreasingMultiplier {
protected:
IncreasingMultiplier(int initialMultiplier = 0, int incrementation = 1)
int getMultiplier() {
mCurrentMultiplier += mIncrementation;
return mCurrentMultiplier - mIncrementation;
}
void setMultiplier(int multiplier) {
mCurrentMultiplier = multiplier;
}
void setIncrementation(int incrementation) {
mIncrementation = incrementation;
}
private:
int mCurrentMultiplier;
int mIncrementation;`
}
class ConstMultiplier {
protected:
int getMultiplier() const {
return 10;
}
}
class NumberLogger {
public:
void log() {
int currentNumber = getNumber(); // How can I call this method?
std::cout << "Current number is " << currentNumber << std::endl;
}
}
template<
class MultiplierPolicy,
class LoggingPolicy
>
class Host : public MultiplierPolicy, public LoggingPolicy {
public:
int getNumber() const {
return mNumber * getMultiplier();
}
private:
int mNumber;
}
Basically, one policy may need to access members defined in the host class, which are in turn dependent on other policies supplied to the host class.
Thanks!
The following code compiles with VS2013 (have not tried with GCC):
#include <iostream>
class IncreasingMultiplier {
protected:
IncreasingMultiplier(int initialMultiplier = 0, int incrementation = 1)
: mCurrentMultiplier(initialMultiplier)
, mIncrementation(incrementation)
{}
int getMultiplier() {
mCurrentMultiplier += mIncrementation;
return mCurrentMultiplier - mIncrementation;
}
void setMultiplier(int multiplier) {
mCurrentMultiplier = multiplier;
}
void setIncrementation(int incrementation) {
mIncrementation = incrementation;
}
private:
int mCurrentMultiplier;
int mIncrementation;
};
class ConstMultiplier {
protected:
int getMultiplier() const {
return 10;
}
};
// Template the logger policy
// Unfortunately - couldn't get host inheritance CRTP pattern
// compiling in Visual Studio 2013 :(
// https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern
template < typename t_Host >
class NumberLogger /*: public t_Host*/ {
public:
void log() {
// This part of the CRTP pattern does work in Visual Studio 2013
int currentNumber = static_cast<t_Host*>(this)->getNumber(); // How can I call this method?
std::cout << "Current number is " << currentNumber << std::endl;
}
};
// Template based on a list of policies
template<
typename PoliciesList
>
class Host : public PoliciesList::MultiplierPolicy, public PoliciesList::LoggingPolicy {
public:
Host() : mNumber(1) {}
int getNumber() /*const*/ {
return mNumber * getMultiplier();
}
private:
int mNumber;
};
// Un-templated policies list
// Could create a macro to declare various policy combinations:
class ConcretePoliciesList_Const
{
public:
typedef Host<ConcretePoliciesList_Const> MyHost;
typedef ConstMultiplier MultiplierPolicy;
typedef NumberLogger<MyHost> LoggingPolicy;
};
class ConcretePoliciesList_Increasing
{
public:
typedef Host<ConcretePoliciesList_Increasing> MyHost;
typedef IncreasingMultiplier MultiplierPolicy;
typedef NumberLogger<MyHost> LoggingPolicy;
};
int main()
{
ConcretePoliciesList_Const::MyHost const_host;
ConcretePoliciesList_Increasing::MyHost increasing_host;
std::cout << "Const policy:" << std::endl;
const_host.log();
const_host.log();
const_host.log();
std::cout << "Increasing policy:" << std::endl;
increasing_host.log();
increasing_host.log();
increasing_host.log();
return 0;
}
The resulting output is:
Const policy:
Current number is 10
Current number is 10
Current number is 10
Increasing policy
Current number is 0
Current number is 1
Current number is 2
EDIT: I basically revamped the whole question so I could provide an executable example...
I have been getting a segmentation fault that I can't figure out. Here is a compacted version of my code. I maintained the original class hierarchy even though some of the classes have no relevant methods since I think that it has something to do with my issue, especially after some of the comments I've been getting.
#import <vector>
using namespace std;
template<class Data = float>
class Vector
{
// All pure virtual functions.
};
template<class Data>
class TranslationVector : public virtual Vector<Data>
{
// All pure virtual functions.
};
template<class Data>
class SimpleVector4 : public virtual Vector<Data>
{
public:
SimpleVector4(const Data d0, const Data d1, const Data d2, const Data d3)
{
fData = new vector<Data> ;
fData->push_back(d0);
fData->push_back(d1);
fData->push_back(d2);
fData->push_back(d3);
}
vector<Data>*
getData()
{
return (fData);
}
private:
vector<Data>* fData;
};
template<class Data>
class SimpleTranslationVector4 : public SimpleVector4<Data> , public TranslationVector<Data>
{
public:
SimpleTranslationVector4(const Data x, const Data y, const Data z, const Data w) :
SimpleVector4<Data> (x, y, z, w)
{
}
};
template<class Data = float>
class Matrix
{
// All pure virtual functions.
};
template<class Data>
class TransformationMatrix : public virtual Matrix<Data>
{
// All pure virtual functions.
virtual void
translate(TranslationVector<Data>* const translation) = 0;
};
template<class Data>
class SimpleMatrix44 : public virtual Matrix<Data>
{
public:
SimpleMatrix44()
{
fData = new vector<Data> (CELLS_IN_MATRIX, 0);
setIdentity();
}
vector<Data>*
getData()
{
return (fData);
}
void
setIdentity()
{
fData->at(0) = 1;
fData->at(1) = 0;
fData->at(2) = 0;
fData->at(3) = 0;
fData->at(4) = 0;
fData->at(5) = 1;
fData->at(6) = 0;
fData->at(7) = 0;
fData->at(8) = 0;
fData->at(9) = 0;
fData->at(10) = 1;
fData->at(11) = 0;
fData->at(12) = 0;
fData->at(13) = 0;
fData->at(14) = 0;
fData->at(15) = 1;
}
private:
static const int CELLS_IN_MATRIX = 16;
vector<Data>* fData;
};
template<class Data>
class SimpleTransformationMatrix44 : public SimpleMatrix44<Data> , public TransformationMatrix<Data>
{
public:
SimpleTransformationMatrix44() :
SimpleMatrix44<Data> ()
{
}
void
translate(TranslationVector<Data>* translation)
{
vector<Data> *data = SimpleMatrix44<Data>::getData();
vector<Data> *transData = ((SimpleVector4<Data>*) translation)->getData();
// The error occurs on this line:
data->at(12) += data->at(0) * transData->at(0) + data->at(4) * transData->at(1) + data->at(8) * transData->at(2);
data->at(13) += data->at(1) * transData->at(0) + data->at(5) * transData->at(1) + data->at(9) * transData->at(2);
data->at(14) += data->at(2) * transData->at(0) + data->at(6) * transData->at(1) + data->at(10) * transData->at(2);
data->at(15) += data->at(3) * transData->at(0) + data->at(7) * transData->at(1) + data->at(11) * transData->at(2);
}
};
int
main(int argc, char** argv)
{
SimpleTransformationMatrix44<float> matrix1;
matrix1.translate(new SimpleTranslationVector4<float> (0.0f, 10.0f, 0.0f, 1.0f));
return 0;
}
I have commented in the code where the error occurs. From debugging I can see that it actually occurs in the size() function of vector and that transData has not been initialized. I can't for the life of me figure out why transData has not been initialized! Any ideas?
Thanks,
Gaz.
Cast of non-inherited classes seems to be your error.
Let's see your code. There is a conversion of SimpleTranslationVector4<float>* to TranslationVector<float>* while invoking the translate function. Then the converted value is converted again into SimpleVector4<float>*. But the SimpleVector4<float> does not inherit TranslationVector<float>.
This code also results in error.
template<class Data>
class SimpleVector4 {
public:
int a;
};
template<class Data>
class TranslationVector {
};
template<class Data>
class SimpleTranslationVector4 : public SimpleVector4<Data>,
public TranslationVector<Data> {
};
int main() {
SimpleTranslationVector4<float> A;
SimpleVector4<float>* b = (SimpleVector4<float>*)&A;
TranslationVector<float>* c = (TranslationVector<float>*)&A;
SimpleVector4<float>* d = (SimpleVector4<float>*)c;
b->a = 1; // ok
d->a = 1; // error
}
You're doing a C-style cast between unrelated types. This is not safe. The fact that you need to do this at all probably indicates a problem in your design, but try replacing this:
vector<Data>* transData = ((SimpleVector4<Data>*) translation)->SimpleVector4<Data>::getData();
with this:
vector<Data>* transData = dynamic_cast<SimpleVector4<Data>*>(translation)->getData();