I am trying to write this code where there are 2 classes inherited from a parent class.But this code breaks when I try to use it in a link list.Here is the code
class airship{
public:
airship(){};
// virtual ~ airship();
virtual void setData (string)=0;
virtual void showData()=0;
void setNext(airship* newptr);
airship* getNext();
void setType(int n){airshipType=n;}
int getType(){return airshipType;}
void setCount(int n){maxPassengerCount=n;};
int getCount(){return maxPassengerCount;}
void setWeight(int n){maxCargoWeight=n;}
int getWeight(){return maxCargoWeight;}
protected:
int maxPassengerCount;
int maxCargoWeight;
int airshipType;
private:
airship* next;
};
class airplane: public airship{
protected:
const char* airplaneName;
int engineType;
double range;
public:
airplane():airship(){};
// ~ airplane();
void setData(string);
void showData();
void setEngine(int n){engineType=n;}
int getEngine(){return engineType;}
void setRange(int n){range=n;}
int getRange();
};
class balloon : public airship{
protected:
const char* balloonName;
int gasType;
double maxAltitude;
public:
balloon():airship(){};
// ~balloon();
void setData(string);
void showData();
void setGas(int);
int getGas();
void setAlt(int);
int getAlt();
};
class mylist{
private:
airship* headAirship;
public:
void createlist(fstream&);
void setAirship(airship* Node){Node=headAirship;}
airship* getAirship(){return headAirship;}
};
void airship::setNext(airship* Node)
{
this->next=Node;
}
void airplane::setData(string line)
{
string line1;
bool flag=true;
int npos=0,nend,count=0;
while(line.c_str()!=NULL && flag)
{
nend=line.find(",",npos);
if (nend!=-1)
{
line1=line.substr(npos,nend);
}
else
{
line1=line;
flag=false;
}
line=line.substr(nend+1,line.length());
if (count==0)
this->airshipType=atoi(line1.c_str());
else if(count==1)
this->airplaneName=line1.c_str();
else if(count==2)
this->maxPassengerCount=atoi(line1.c_str());
else if(count==3)
this->maxCargoWeight=atoi(line1.c_str());
else if(count==4)
this->engineType=atoi(line1.c_str());
else
this->range=atoi(line1.c_str());
count=count+1;
}
}
void balloon::setData(string line)
{
string line1;
bool flag=true;
int npos=0,nend,count=0;
while(line.c_str()!=NULL && flag)
{
nend=line.find(",",npos);
if (nend!=-1)
{
line1=line.substr(npos,nend);
}
else
{
line1=line;
flag=false;
}
line=line.substr(nend+1,line.length());
if (count==0)
this->airshipType=atoi(line1.c_str());
else if(count==1)
this->balloonName=line1.c_str();
else if(count==2)
this->maxPassengerCount=atoi(line1.c_str());
else if(count==3)
this->maxCargoWeight=atoi(line1.c_str());
else if(count==4)
this->gasType=atoi(line1.c_str());
else
this->maxAltitude=atoi(line1.c_str());
count=count+1;
}
}
void mylist::createlist(fstream &myfile)
{
string ipdata;
int type;
while (getline(myfile,ipdata))
{
airship* newNode;
type=ipdata.find(",",0);
string ch=ipdata.substr(type-1,type);
if (atoi(ch.c_str())==0)
{
airplane* planeNode=new airplane();
planeNode->setData(ipdata);
newNode=planeNode;
}
else
{
balloon* balloonNode=new balloon();
balloonNode->setData(ipdata);
newNode=balloonNode;
}
newNode->setNext(headAirship);
this->headAirship=newNode;
}
}
int main()
{
mylist* list=0;
airship* firstNode=0,*otherNode=0;
/*if(argv[1]==NULL)
{
cout<<"File not Found"<<endl;
return -1;
}*/
fstream ipFile("data.txt",ios::in | ios::out);
if(ipFile.is_open())
{
list->createlist(ipFile);
}
list->setAirship(firstNode);
return 0;
}
The airplane::setdata(string) function does not work properly and it is not able to detect headAirship pointer in the createList function.And that is why I get a memory exception error in the createlist function when I try to do this:newNode->setNext(headAirship);
Unhandled exception at 0x00912ae0 in Assignment4Solution2.exe: 0xC0000005:
Access violation reading location 0x00000000.
I think the problem is here:
mylist* list=0;
In that line, you create a pointer to a myList object, but you don't make it point to any such object; it's pointing to address 0
Then you do
list->createlist(ipFile);
Since list is not pointing an address containing a myList object, invoking any of the myList methods is supposed to give the error you observed: Access violation reading location 0x00000000.
Instead, when you create the list pointer, invoke the constructor for myList so that the object gets created and the pointer is initialized to point to it
myList * list = new myList();
Hope that helps :)
Related
I have 3 classes in my program that interact with each other and contain each other's instances:
class Inventory
{
public:
// Increment Data Members
void incrementHerbs() { herbs++; }
void incrementHealth() { health++; }
void incrementGold() { gold++; }
// Getters
int getHerbs() { return herbs; }
int getHealth() { return health; }
int getGold() { return gold; }
private:
int herbs = 0;
int health = 3;
int gold = 0;
};
class Player
{
public:
void setRow(int row) { this->rowCoordinate = row; }
void setCol(int col) { this->colCoordinate = col; }
int getRow() { return rowCoordinate; }
int getCol() { return colCoordinate; }
Inventory getBag() { return Bag; }
private:
int rowCoordinate;
int colCoordinate;
Inventory Bag;
};
class Board
{
public:
int getNumRows() { return numRows; }
int getNumCols() { return numCols; }
Player getPlayer() { return User; }
private:
int numRows;
int numCols;
char** maze;
Player User;
};
I am only instantiating a Board object in the main function. At a point in my program, I want to be able to increment the herb count in the inventory class through that object.
I have tried doing:
Board board;
board.getPlayer().getBag().incrementHerbs();
This call compiles without any errors but when I print out the herb count afterwards, the herb count is still the same.
It did not increment. What can be going wrong and what can I do?
What can be going wrong and what can I do?
In your Player class, your getBag() function returns a copy of Inventory (i.e. member Bag).
Inventory getBag() { return Bag; }
//^^^^^^----> is copy!
You need to return the reference in order to modify it
Inventory& getBag() { return Bag; }
//^^^^^^^^
The same issue with the Board's function getPlayer()
Player getPlayer() { return User; }
//^^^^----> is copy!
you need
Player& getPlayer() { return User; }
//^^^^^^
And here's a demo.
Hi im doing little project tomy school and keep getting weird for me error.
While calling one of methods in my object this pointer is set to 0xcdcdcdcd. i googled it and found some info about erasing memory or destroing objects before calling, but i make sure no destructors are called before.
World.h
class Organism;
class Human;
class World
{
private:
vector <Organism*> organisms;
vector <Organism*> organismsToAdd;
vector <string> logs;
int turn_;
void initializeWorld();
void drawInterface();
void drawInfo();
void drawOrganisms();
void nextTurn();
bool isPositionTaken(int x, int y);
Organism* getOrganism(int x, int y);
void queueOrganismToAdd(Organism* newOrganism);
void addQueuedOrganisms();
void generateStartOrganisms();
bool isPlayerAlive();
public:
void executeMove(Organism* moving, int toX, int toY); //here's the problem
bool isPositionValid(int x, int y);
World(int x, int y);
struct
{
int x_, y_;
} worldSize;
void startGame();
~World();
};
executeMove
void World::executeMove(Organism* moving, int toX, int toY)
{
cout << moving->getSign();
getch();
if (!isPositionTaken(toX, toY)) // <- here it brake
{
moving->setPosition(toX, toY);
}
else if (moving->getSign() == getOrganism(toX, toY)->getSign())
{
//multiply
//make log
}
else {
if (!moving->specialCollision((getOrganism(toX, toY)))) return;
if (!getOrganism(toX, toY)->specialCollision(moving)) return;
if (moving->getPower() >= getOrganism(toX, toY)->getPower())
{
//log
//delete losser
}
else
{
//log
//delete losser
}
moving->setPosition(toX, toY);
}
}
isPositioinTaken
bool World::isPositionTaken(int x, int y)
{
for (int i = 0; i < this->organisms.size(); ++i) // here this is set to 0xcdcdcdcd
{
if (organisms[i]->getPositionX() == x && organisms[i]->getPositionY() == y) return true;
}
return false;
}
Method isPositionTaken is worlking well in other parts of project so im totally lost if finding whats wrong, i aprreciate any help
Since the organisms member has a default constructor, the only way to see this behavior at the line you indicated is if the call to executeMove() was using a pointer which was uninitialized.
Something like:
World *ptr; // not initialized on stack
...
ptr->executeMove();
Or this method was called from another method with the same problem.
I'm using visual studio , with this code it gives me an "Assertion failed" message .
I have class (C) which have an integer pointer in it with regular set and print methods ,
This is my code :
class C
{
int* p;
public:
void print();
void set_value(int);
int get_value();
C(); // default cinstructor
C(int); //constructor with parameters (overloading constructor)
~C();
};
int C::get_value() {
return *p;
}
void test(C ob1) {
ob1.print();
}
C::~C()
{
cout<<p<<" has been destroyed \n";
if (p!=0)
delete p;
}
C::C()
{
p=0;
}
C::C(int x)
{
p=new int;
*p=x;
}
void C::print()
{
if (p!=0)
cout<<"p = "<<p<<"\t"
<<"*p = "<<*p<<endl;
else
cout<<"Empty pointer"<<endl;
}
void C::set_value(int x)
{
if (p==0)
p = new int;
*p=x;
}
void main()
{
C x,y(20);
test(y);
}
anyone can help ? thanks in advance .
m working on ns2...did some changes in aodv.cc and added some functions of my own
void nb_traffic_update(int id,struct nb_traffic_stat **nblist,int nid,int flag,int hop_count)
..to detect sinkhole attack..when m running the code with small no of nodes i get results but when i increase the number of nodes i get segmentation fault.
This is my nb_traffic.h file
struct nb_traffic_stat
{
int id;
int recvrequest;
int routereply;
int no_of_hops;
//int no_of_updation;
struct nb_traffic_stat *next;
};
struct traffic_stat
{
int id;
struct nb_traffic_stat **list;
struct traffic_stat *next;
};
struct ftraffic_stat
{
int sendrequest;
int routereply;
};
modification to aodv.cc
struct traffic_stat *tlist=NULL,*ttail=NULL;
void
AODV::recvReply(Packet *p) {
...
if (ih->daddr() == index) { // If I am the original source
.....
nb_traffic_update(index,&nblist,ih->saddr(),1,rp->rp_hop_count);//1 is for receiving the route reply
}
}
void
AODV::recvRequest(Packet *p) {
....
/*after ensuring this is the new routerequest*/
struct hdr_cmn *ch = HDR_CMN(p);
if(ch->num_forwards()==1)
{
nb_traffic_update(index,&nblist,rq->rq_src,0,0);//0 is for receiving the request
}
}
my neighbour traffic update function
void nb_traffic_update(int id,struct nb_traffic_stat **nblist,int nid,int flag,int hop_count)
{
int n;
//printf("inside nb_traffic_update:%d\n",id);
if(*nblist==NULL)
{
struct nb_traffic_stat *ptr;
ptr=(struct nb_traffic_stat*)malloc(sizeof(struct nb_traffic_stat));
ptr->id=nid;
ptr->next=NULL;
if(flag==0)
{
ptr->recvrequest=1;
ptr->routereply=0;
ptr->no_of_hops=0;
//ptr->no_of_updation=0;
}
else
{
ptr->recvrequest=0;
ptr->routereply=1;
ptr->no_of_hops=hop_count;
//ptr->no_of_updation=1;
}
*nblist=ptr;
struct traffic_stat *sptr;
sptr=tlist;
while(sptr!=NULL&&sptr->id!=id)
{
sptr=sptr->next;
}
assert(sptr!=NULL);
sptr->list=nblist;
}
else
{
int found=0;
struct nb_traffic_stat *tptr,*prevtptr;
tptr=*nblist;
while(tptr!=NULL&&tptr->id<=nid)
{
if(tptr->id==nid)
{
found=1;
break;
}
prevtptr=tptr;
tptr=tptr->next;
}
if(found)
{
if(flag==0)
{
tptr->recvrequest++;
}
else
{
tptr->routereply++;
tptr->no_of_hops=hop_count;
//tptr->no_of_updation++;
}
}
else
{
struct nb_traffic_stat *ptr;
ptr=(struct nb_traffic_stat*)malloc(sizeof(struct nb_traffic_stat));
ptr->id=nid;
if(flag==0)
{
ptr->recvrequest=1;
ptr->routereply=0;
ptr->no_of_hops=0;
//ptr->no_of_updation=0;
}
else
{
ptr->recvrequest=0;
ptr->routereply=1;
ptr->no_of_hops=hop_count;
//ptr->no_of_updation=1;
}
ptr->next=prevtptr->next;
prevtptr->next=ptr;
}
}
}
You are not checking for nblist to be NULL inside the nb_traffic_update(int, nb_traffic_stat**, int, int, int) function, which leads to the segfault.
Also inside the conditional statement if (*nblist==NULL) you are doing: *nblist=ptr;. Which means *NULL = ptr; which may cause the segfault.
Run your tcl with gdb it will show the function which cause the segment fault...
for ex, gdb -args ns path/to/tcl/script.tcl
HI,
I got this Error in my code i can't understand how to pass a command line argument while the exe of my programe is not created how i write the name of that .exe file.
C:\Program Files\Microsoft Visual Studio\MyProjects\filehandling\file.cpp(205) : error C2451: conditional expression of type 'class std::basic_fstream >' is illegal
Ambiguous user-defined-conversion
#include "iostream"
#include "cstdlib"
#include "cstdio"
#include "ctime"
#include "fstream"
#include "istream"
using namespace std;
class shapes
{
public:
virtual void draw()=0;
virtual void save(fstream &out)=0;
virtual void open(fstream &in)=0;
};
class myline : public shapes
{
private:
int sx,sy,ex,ey,color;
public:
myline()
{}
myline(int x1, int y1, int x2, int y2, int clr)
{
sx=x1;
sy=y1;
ex=x2;
ey=y2;
color=clr;
}
void draw()
{
cout<<"Line-draw()"<<endl;
}
void save(fstream &out)
{
out<<"L"<<"\n";
out<<sx<<""<<sy<<""<<ex<<""<<ey<<""<<color<<"\n";
}
void open(fstream &in)
{
in>>sx>>sy>>ex>>ey>>color;
}
};
class myrectangle: public shapes
{
private:
int sx,sy,ex,ey,color;
public:
myrectangle()
{}
myrectangle(int x1, int y1,int x2, int y2,int clr)
{
sx=x1;
sy=y1;
ex=x2;
ey=y2;
color=clr;
}
void draw()
{
cout<<"Rectangle-draw()"<<endl;
}
void save(fstream &out)
{
out<<"R"<<"\n";
out<<sx<<""<<sy<<""<<ex<<""<<ey<<""<<color<<"\n";
}
void open(fstream &in)
{
in>>sx>>sy>>ex>>ey>>color;
}
};
class mycircle: public shapes
{
private:
int sx, sy, radius, color;
public:
mycircle()
{
}
mycircle(int x1, int y1, int r, int clr)
{
sx=x1;
sy=y1;
radius=r;
color=clr;
}
void draw()
{
cout<<"Circle-draw()"<<endl;
}
void save(fstream &out)
{
out<<"C"<<"\n";
out<<sx<<""<<sy<<""<<radius<<""<<color<<"\n";
}
void open(fstream &in)
{
in>>sx>>sy>>radius>>color;
}
};
struct node
{
void*obj;
node*link;
};
class objarray
{
private:
node*head;
public:
objarray()
{
head= NULL;
}
void add(void*o)
{
node*temp = new node;
temp->obj=o;
temp->link=NULL;
if(head==NULL)
head=temp;
else
{
node*q;
q=head;
while(q->link != NULL)
q=q->link;
q->link=temp;
}
}
void*getobj(int i)
{
node*q;
q=head;
int n;
for (n=1; n<i; n++)
{
q=q->link;
}
return(q->link);
}
int getcount()
{
int n=0;
node*q;
q=head;
while(q != NULL)
{
q=q->link;
n++;
}
return n;
}
~objarray()
{
node *q;
q=head;
while(q != NULL)
{
head = head->link;
delete q;
q=head;
}
}
};
int main(int argc ,char*argv[])
{
fstream file;
char choice;
int clmum,sx,sy,ex,ey,rad;
shapes*ptr;
objarray arr;
char a[2];
int i;
if(argc==2)
file.open(argv[1], ios::in|ios::out);
while(file)
{
file>>a;
if(strcmp(a,"L")==0)
{
myline*l = new myline();
l->open(file);
arr.add(l);
}
if(strcmp(a,"R")==0)
{
myrectangle *a=new myrectangle();
a->open(file);
arr.add(a);
}
if(strcmp(a,"C")==0)
{
mycircle*c=new mycircle();
c->open(file);
arr.add(c);
}
}
int count = arr.getcount();
for(i=1; i<=count; i++)
{
ptr=(shapes*)arr.getobj(i);
ptr->draw();
}
srand((unsigned ) time(NULL));
while(1)
{
cout<<endl<<"1.Line 2. Rectanle 3.Circle 4.Exit"<<endl;
cout<<"Your Choice:";
fflush(stdin);
cin.get(choice);;
clmum=rand()%16;
sx=rand()%638;
sy=rand()%478;
ex=rand()%638;
ey=rand()%478;
rad=rand()%200;
myline*l;
myrectangle*a;
mycircle*c;
switch(choice)
{
case '1':
l = new myline(sx, sy, ex,ey,clmum);
if(l=NULL)
exit(1);
arr.add(l);
cout<<"Following Line added to array"<<endl;
cout<<"sx="<<sx<<"sy="<<sy<<"ex ="<<ex<<"ey ="<<ey<<"color ="<<clmum<<endl;
break;
case '2':
a = new myrectangle(sx,sy,ex,ey,clmum);
if(a==NULL)
exit(1);
arr.add(a);
cout<<"Following Rectangle added to array"<<endl;
cout<<"sx="<<sx<<"sy="<<sy<<"ex ="<<ex<<"ey ="<<ey<<"color ="<<clmum<<endl;
break;
case '3':
c=new mycircle(sx,sy,rad,clmum);
if(c==NULL);
exit(1);
arr.add(c);
cout<<"Following Circle added to array"<<endl;
cout<<"sx="<<sx<<"sy="<<sy<<"rad ="<<rad<<"color"<<clmum<<endl;
break;
case '4':
if(argc==1)
{
cout<<"Enter File name:";
char name[67];
cin>>name;
file.open(name,ios::out);
}
count=arr.getcount();
file.seekp(0L,ios::beg);
file.clear();
for(i=1; i<=count;i++)
{
ptr=(shapes*) arr.getobj(i);
ptr->save(file);
}
file.close();
cout<<"Array save to file......exiting"<<endl;
exit(1);
}
}
return 0;
}
Here's your problem area (at least the area of the problem you've identified):
while(file)
{
file>>a;
What you're getting should be a warning, not an error -- there's one conversion that should be used here. Even though what it's told you is technically wrong, it's still done you a favor by identifying buggy code. The problem is that you're testing whether the read succeeded before you actually do the read. Therefore, when/if the read fails, you'll execute another iteration of your loop before the loop exits.
You want to combine the reading and testing so you'll detect a failed read immediately after it happens. You can do this by replacing both of the lines above with: while (file >> a) {
Your problem is the line 205, while (file). It should be while (!file.eof())
As pointed out by CariElf, your file won't turn to NULL or 0 or something like that during that while loop. On the other hand, the file's "end of file" marker will be true at some point.
About your... well, other question I guess ("i can't understand how to pass a command line argument while the exe of my programe is not created"):
You can tell VS you want to pass some command line arguments by changing "Command Arguments" in Project->Properties, on the Configuration Properties->Debugging tab.