Program not running on some IDE's, issue with classes - c++

Can someone help me find the issue in my code here?
I keep getting an error that just says program terminated. It runs on certain ide's but not others, and it hurts because I felt like I was starting to grasp the concepts of OOP, but guess not. The main idea of the program is to read the shape data into a pointer array and then display all of the information about the shapes.
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
// Global constant for array size.
const int SIZE = 99;
// Base Class
class Shape
{
protected:
char type;
int serNo;
int dim1;
int dim2;
public:
// Default constructor
Shape()
{
type = ' ';
serNo = 0;
dim1 = 0;
dim2 = 0;
}
// Constructor #1
Shape(char t, int s, int d1, int d2)
{
type = t;
serNo = s;
dim1 = d1;
dim2 = d2;
}
// Get type
char getType()
{
return type;
}
// Get serial number
int getSerNo()
{
return serNo;
}
// Get dimension1
int getDim1()
{
return dim1;
}
// Get dimension2
int getDim2()
{
return dim2;
}
// Destructor
~Shape()
{}
};
// Circle Class (Derived from Shape)
class Circle : public Shape
{
public:
Circle(char t, int s, int d1, int d2) : Shape(t, s, d1, d2)
{}
};
// Spray Class (Derived from Circle)
class Spray : public Circle
{
public:
// Constructor
Spray(char t, int s, int d1, int d2) : Circle(t, s, d1, d2)
{}
};
// Rectangle Class (Derived from Shape)
class Rectangle : public Shape
{
public:
// Constructor
Rectangle(char t, int s, int d1, int d2) : Shape(t, s, d1, d2)
{}
};
// Square Class (Derived from Rectangle)
class Square : public Rectangle
{
public:
// Constructor
Square(char t, int s, int d1, int d2) : Rectangle(t, s, d1, d2)
{}
};
class mgrShape : public Shape
{
protected:
int recordCount;
Shape * shapeArr[SIZE] = {nullptr}; // Manager owns the main data
//structure
public:
// Constructor.
mgrShape()
{
populateShapeData();
}
// Populate the shapeArr from file.
void populateShapeData()
{
fstream inputFile;
string fileName = "shaperecords.txt";
inputFile.open(fileName);
while(inputFile >> type >> serNo >> dim1 >> dim2)
{
if (type == 'C')
shapeArr[recordCount] = new Circle(type, serNo, dim1, dim2);
else if (type == 'R')
shapeArr[recordCount] = new Rectangle(type, serNo, dim1, dim2);
else if (type == 'S')
shapeArr[recordCount] = new Spray(type, serNo, dim1, dim2);
else if (type == 'Q')
shapeArr[recordCount] = new Square(type, serNo, dim1, dim2);
recordCount++;
}
inputFile.close();
}
//Display all of the shapes.
void displayAll()
{
for (int i = 0; i < recordCount; i++)
{
if (shapeArr[i]->getType() == 'C')
{
cout << "Circle Found!" << endl;
cout << shapeArr[i]->getType() << endl;
cout << shapeArr[i]->getSerNo() << endl;
cout << shapeArr[i]->getDim1() << endl;
cout << shapeArr[i]->getDim2() << endl;
}
else if (shapeArr[i]->getType() == 'R')
{
cout << "Rectangle Found!" << endl;
cout << shapeArr[i]->getType() << endl;
cout << shapeArr[i]->getSerNo() << endl;
cout << shapeArr[i]->getDim1() << endl;
cout << shapeArr[i]->getDim2() << endl;
}
else if (shapeArr[i]->getType() == 'S')
{
cout << "\nSpray Found!" << endl;
cout << shapeArr[i]->getType() << endl;
cout << shapeArr[i]->getSerNo() << endl;
cout << shapeArr[i]->getDim1() << endl;
cout << shapeArr[i]->getDim2() << endl;
}
else if (shapeArr[i]->getType() == 'Q')
{
cout << "Square Found!" << endl;
cout << shapeArr[i]->getType() << endl;
cout << shapeArr[i]->getSerNo() << endl;
cout << shapeArr[i]->getDim1() << endl;
cout << shapeArr[i]->getDim2() << endl;
}
}
}
// Clear the dynamically allocated memory from shapeArr.
~mgrShape()
{
for (int i = 0; i < recordCount; i++)
delete shapeArr[i];
}
};
int main()
{
mgrShape ms;
ms.displayAll();
return 0;
}
//And here's the input file's contents
//C 1001 30 -1
//R 1002 14 10
//S 1003 30 20
//Q 1004 28 -1
//S 1005 30 75

Related

To convert multi level to hierarchy inheritance in c++

When I tried to convert it the class result can't get the data from class marks even if I made the data variables of marks public I don't know why. I also declared a object of class marks in result and then tried to access it but failed again I am new to coding so don't know all the syntax correctly your help will be of great use
#include <string.h>
#include <iostream>
using namespace std;
class student {
private:
int rl;
char nm[20];
public:
void read();
void display();
};
class marks : public student {
protected:
int s1;
int s2;
int s3;
public:
void getmarks();
void putmarks();
};
class result : public marks {
private:
int t;
float p;
char div[10];
public:
void process();
void printresult();
};
void student::read() {
cout << "enter Roll no and Name " << endl;
cin >> rl >> nm;
}
void student::display() {
cout << "Roll NO:" << rl << endl;
cout << "name : " << nm << endl;
}
void marks ::getmarks() {
cout << "enter three subject marks " << endl;
cin >> s1 >> s2 >> s3;
}
void marks ::putmarks() {
cout << "subject 1:" << s1 << endl;
cout << "subject 2 :" << s2 << endl;
cout << "subject 3:" << s3 << endl;
}
void result::process() {
t = s1 + s2 + s3;
p = t / 3.0;
p >= 60 ? strcpy(div, "first")
: p >= 50 ? strcpy(div, "second")
: strcpy(div, "third");
}
void result::printresult() {
cout << "total = " << t << endl;
cout << "per = " << p << "%" << endl;
cout << "div = " << div << endl;
}
int main(){
result x;
x.read();
x.getmarks();
x.process();
x.display();
x.putmarks();
x.printresult();
}
#include<iostream>
#include<string.h>
using namespace std;
class marks // parent class
{
protected:
int s1;
int s2;
int s3;
public:
void getmarks();
void putmarks();
};
class student : public marks // child class
{
private:
int rl;
char nm[20];
public:
void read();
void display();
};
class result : public marks// child class
{
private:
int t;
float p;
char div[10];
public:
void process();
void printresult();
};
void student::read()
{
cout<<"enter Roll no and Name "<<endl;
cin>>rl>>nm;
}
void student:: display()
{
cout <<"Roll NO:"<<rl<<endl;
cout<<"name : "<<nm<<endl;
}
void marks ::getmarks()
{
cout<<"enter three subject marks "<<endl;
cin>>s1>>s2>>s3;
}
void marks ::putmarks()
{
cout <<"subject 1:"<<s1<<endl;
cout<<"subject 2 :"<<s2<<endl;
cout <<"subject 3:"<<s3<<endl;
}
void result::process()
{
t= s1+s2+s3;
p = t/3.0;
p>=60?strcpy(div,"first"):p>=50?strcpy(div, "second"): strcpy(div,"third");
}
void result::printresult()
{
cout<<"total = "<<t<<endl;
cout<<"per = "<<p<<"%"<<endl;
cout<<"div = "<<div<<endl;
}
int main()
{
result x;
student y;
y.read();
x.getmarks();
x.process();
y.display();
x.putmarks();
x.printresult();
}

0xC0000005: Access violation reading location 0xCDCDCDC1

I wrote the code that can generate random Geometry figures and display it in cmd in text form.
Here is my 3 files:
Geometry.h
#pragma once
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#include <iostream>
#include <time.h>
#include <fstream>
#include <string>
#define PI 3.1415926535
using namespace std;
enum color { White, Red, Green, Blue, Yellow, Black };
enum _shape { line, rectangle, circle, picture }; //to roll shapes
void print_color(color c);
//--------------------------Point---------------------------
class Point {
private:
int m_xc, m_yc; //(x,y) coordinats
public:
Point(int x = 0, int y = 0) : m_xc(x), m_yc(y) {}
int x(void) const { return m_xc; };
int y(void) const { return m_yc; };
Point operator+(const Point& p) const
{
return Point(m_xc+p.m_xc, m_yc+p.m_yc);
}
Point& operator+=(const Point& p) //move point
{
m_xc += p.m_xc;
m_yc += p.m_yc;
return *this;
}
friend ostream& operator<<(ostream& os, const Point& p);
Point move(int x, int y){
m_xc += x;
m_yc += y;
return *this;
}
};
//------------------------Shape-----------------------------
class Shape {
protected:
Point m_org;
color m_color;
_shape m_shape;
public:
Shape(const Point& p1 = 0, color c = White, _shape sh = line) : m_org(p1), m_color(c), m_shape(sh){};
virtual ~Shape() = 0 {};
virtual void move(const Point& p) = 0;
virtual void draw(char tabs) const = 0;
virtual void Who_am_I() const = 0;
virtual double Area() const { return 0; };
virtual void Save2File(ofstream &myfile) const = 0;
};
//------------------------Line---------------------------------
class Line : public Shape {
protected:
Point m_end; // line end
public:
Line(const Point& p1, const Point& p2, color c) : Shape(p1, c, line), m_end(p2) {}
void move(const Point& p)
{
m_org += p;
m_end += p;
}
void draw(char tabs) const;
void Who_am_I() const {
print_color(m_color);
cout << "Line";
}
double length() const;
double Area() const { return 0; };
void Save2File(ofstream &myfile) const;
};
//----------------------Rectangle-------------------------------
class Rectangle : public Shape {
protected:
int width;
int height;
public:
Rectangle(const Point& p1, color c = White, int w = 0, int h = 0) : Shape(p1, c, rectangle), width(w), height(h) {}
void move(const Point& p)
{
m_org += p;
}
void draw(char tabs) const;
void Who_am_I() const {
print_color(m_color);
cout << "Rectangle";
}
double Area() const { return width*height; };
void Save2File(ofstream &myfile) const;
};
//----------------------Circle---------------------------
class Circle : public Shape {
protected:
int radius;
public:
Circle(const Point& p1, color c = White, int r = 0) : Shape(p1, c, circle), radius(r) {};
void move(const Point& p)
{
m_org += p;
}
void draw(char tabs) const;
void Who_am_I() const {
print_color(m_color);
cout << "Circle";
}
double Area() const { return PI*(double)radius*(double)radius; };
void Save2File(ofstream &myfile) const;
};
//--------------------------Picture-------------------------
class Picture : public Shape {
private:
Picture(const Picture&); //CCtor is not accessible from main
protected:
Shape** m_shapes; //array of pointers to shapes
int m_count; //number of shapes
static unsigned idx; //number of pictures created for debug
public:
Picture(const Point& p1 = 0, color c = White) : Shape(p1, c, picture), m_count(0){ idx++; }
~Picture();
void insert_shape(Shape* sh);
void draw(char tabs) const;
void move(const Point& p){ m_org += p; };
void Who_am_I() const {
print_color(m_color);
cout << "Picture";
}
void Save2File(ofstream &myfile) const;
int get_count(void){ return m_count; }
double Area() const;
unsigned GetAmPic(void) { return idx; }
};
Geometry.cpp
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#include "geometry.h"
using namespace std;
unsigned Picture::idx = 0;
ostream& operator<<(ostream& os, const Point& p)
{
os << '(' << p.x() << ',' << p.y() << ')';
return os;
}
void print_color(color c) {
string color_print[6] = { "White ", "Red ", "Green ", "Blue ", "Yellow ", "Black " };
cout << color_print[(int)c];
}
//------------------Line methods--------------------
void Line::draw(char tabs) const
{
cout << string(tabs, '\t');
Who_am_I();
cout << " from " << m_org << " to " << m_end << endl;
}
double Line::length() const
{
return sqrt((double)((m_org.x()-m_end.x())*(m_org.x()-m_end.x()) + (m_org.y()-m_end.y())*(m_org.y()-m_end.y())));
}
void Line::Save2File(ofstream& myfile) const {// save to file
myfile << 'L' << " " << m_color << " " << m_org.x() << " " << m_org.y() << " "
<< m_end.x() << " " << m_end.y() << endl;
}
//------------------Rectangle methods----------------
void Rectangle::draw(char tabs) const
{
cout << string(tabs, '\t');
Point temp1 = m_org;
Point temp2 = m_org;
Line l1(temp1, temp2.move(width, 0), m_color);
temp1 = temp2;
Line l2(temp2, temp1.move(0, height), m_color);
temp2 = temp1;
Line l3(temp1, temp2.move(-width, 0), m_color);
temp1 = temp2;
Line l4(temp2, temp1.move(0, -height), m_color);
Who_am_I(); cout << endl;
cout << string(tabs, '\t'); l1.draw(1);
cout << string(tabs, '\t'); l2.draw(1);
cout << string(tabs, '\t'); l3.draw(1);
cout << string(tabs, '\t'); l4.draw(1);
}
void Rectangle::Save2File(ofstream& myfile) const {// save to file
myfile << 'R' << " " << m_color << " " << m_org.x() << " " << m_org.y() << " " << width
<< " " << height << endl;
}
//----------------------Circle methods---------------------------
void Circle::draw(char tabs) const
{
cout << string(tabs, '\t');
Who_am_I();
cout << " Center in " << m_org << " Radius is " << radius << endl;
}
void Circle::Save2File(ofstream& myfile) const {// save to file
myfile << 'C' << " " << m_color << " " << m_org.x() << " " << m_org.y() << " "
<< radius << endl;
}
//----------------------Picture methods--------------------------
void Picture::insert_shape(Shape* s) // insert a new shape to picture
{
if (m_count == 0) {//new picture creating
m_shapes = new Shape*[1];
if (!m_shapes)
cout << "Can't allocate memory!";
}
if (m_count > 0){
Shape** temp = new Shape*[m_count];
memcpy(temp, m_shapes, sizeof(Shape*)*m_count); //save to temp
delete m_shapes; //delete old array
m_shapes = new Shape*[m_count + 1]; //add 1 more place
if (!m_shapes)
cout << "Can't allocate memory!";
memcpy(m_shapes, temp, sizeof(Shape*)*m_count); //return to array
delete temp;
}
m_shapes[m_count] = s; // insert the new shape into the last slot in the array
m_shapes[m_count]->move(m_org); //adjusts the location of the shape
m_count++; // increment the number of shapes in picture
}
void Picture::draw(char tabs) const
{
cout << string(tabs, '\t');
cout << "------------------ ";
Who_am_I();
cout << " ----------------------" << endl;
for (unsigned i = 0; i < m_count; i++)
{
m_shapes[i]->draw(tabs + 1); // draw each shape
}
cout << string(tabs, '\t');
cout << "------------------ End ";
Who_am_I();
cout << " ------------------ " << endl;
}
double Picture::Area() const //sum of areas of all shapes in the picture
{
double area = 0;
for (int i = 0; i < m_count; i++)
{
area += m_shapes[i]->Area();
}
return area;
}
Picture::~Picture()
{
for (int i = 0; i < m_count; i++){
if (m_shapes[i])
delete m_shapes[i];
}
Who_am_I(); cout << " deleting..." << endl;
// sometimes (every 5-10 runs) error here. can't reproduce and debug
if (m_shapes)
delete m_shapes;
// seems like program try to delete already freed memory
}
void Picture::Save2File(ofstream& myfile) const // save to file
{
myfile << 'P' << " " << m_color << " " << m_org.x() << " " << m_org.y() << endl;
for (int i = 0; i < m_count; i++)
m_shapes[i]->Save2File(myfile);
myfile << 'E' << endl; // end of a picture
}
drawing_app.cpp
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
#define new DEBUG_NEW
#include "geometry.h"
#include <iostream>
#define MAX_PICS_IN_PIC 3
#define MAX_SHAPES 5
using namespace std;
void randomizer(Picture*, int); //recursive function
Picture* Load(istream&);
Point GenP(void);
color GenC(void);
int GenLen(void);
int main(void)
{
srand((unsigned int)time(NULL));
Picture *main_pic = new Picture(Point(0, 0), GenC());
ofstream myfile_write("myfile.txt", ios::out);
if (!myfile_write.is_open())
cout << "Can't open file!" << endl;
randomizer(main_pic, MAX_PICS_IN_PIC); //recursive function
main_pic->Save2File(myfile_write); //save picture to file
myfile_write.close();
cout << " Created Picture:" << endl << endl;
main_pic->draw(0); //draw the main picture
cout << "Created: " << main_pic->GetAmPic() << " pictures." << endl; // for debugging
delete[] main_pic;
ifstream myfile_read("myfile.txt", ios::in);
if (!myfile_read.is_open())
cout << "Can't open file!" << endl;
Picture* buff_pic = Load(myfile_read); //load the picture from the file
cout << endl << endl << " Loaded Picture:" << endl << endl;
buff_pic->draw(0); //display loaded picture
myfile_read.close();
delete[] buff_pic;
cout << "\nLeaks: " << _CrtDumpMemoryLeaks() << endl;
return 0;
}
void randomizer(Picture* pic, int count) {
for (int i = 0; i < MAX_SHAPES; i++){
Point p1 = GenP(); //m_org of the shape
color c = GenC(); //roll random color
_shape shape;
shape = (_shape)(rand() % 4); //roll random shape
if (shape == line){
Point p2 = GenP();
Line* _line = new Line(p1, p2, c);
pic->insert_shape(_line);
}
if (shape == rectangle){
Rectangle* _rect = new Rectangle(p1, c, GenLen(), GenLen());
pic->insert_shape(_rect);
}
if (shape == circle){
Circle* _circ = new Circle(p1, c, GenLen());
pic->insert_shape(_circ);
}
if (shape == picture){
if (count > 0){
Picture* inner_pic = new Picture(p1, c);
count--;
randomizer(inner_pic, count);
pic->insert_shape(inner_pic);
}
else return;
}
}
}
Picture* Load(istream& myfile) {
int m_color, m_org_x, m_org_y;
char m_shape;
myfile >> m_shape >> m_color >> m_org_x >> m_org_y; //read first line
Picture* pic = new Picture(Point(m_org_x, m_org_y), (color)m_color); //create the main picture
myfile >> m_shape; //read next line for shape
while (m_shape != 'E')
{
if (m_shape == 'L'){
int m_end_x, m_end_y;
myfile >> m_color >> m_org_x >> m_org_y >> m_end_x >> m_end_y;
Line* _line = new Line(Point(m_org_x, m_org_y), Point(m_end_x, m_end_y), (color)m_color);
pic->insert_shape(_line);
}
if (m_shape == 'C'){
int radius;
myfile >> m_color >> m_org_x >> m_org_y >> radius;
Circle* Circel = new Circle(Point(m_org_x, m_org_y), (color)m_color, radius);
pic->insert_shape(Circel);
}
if (m_shape == 'R') {
int m_width, m_height;
myfile >> m_color >> m_org_x >> m_org_y >> m_width >> m_height;
Rectangle* Rect = new Rectangle(Point(m_org_x, m_org_y), (color)m_color,
m_width, m_height);
pic->insert_shape(Rect);
}
if (m_shape == 'P') {
myfile.seekg(-1, ios::cur);
Picture* inner_pic = Load(myfile);
pic->insert_shape(inner_pic);
}
myfile >> m_shape;
}
return pic;
}
Point GenP(){ //roll random point x = 0 to 30, y = 0 to 30
Point p(rand() % 31, rand() % 31);
return p;
}
color GenC(){ //generate random color
return (color)(rand() % 6);
}
int GenLen(){ // generate random length from 1 to 50
return rand() % 50 + 1;
}
Every 5-10 runs I got strange error:
Unhandled exception at 0x5214A9E8 (msvcr120d.dll) in Geometry.exe: 0xC0000005: Access violation reading location 0xCDCDCDC1.
Referring me to Destructor of Picture class. I can't reproduce this error and can't find the source of this error. Do you have any ideas how I can debug it?
The obvious error is that it is entirely (and easily) possible to attempt to delete an uninitialized m_shapes pointer in the Picture destructor.
The outline of your code is this:
class Picture : public Shape {
private:
Picture(const Picture&); //CCtor is not accessible from main
protected:
Shape** m_shapes; //array of pointers to shapes
int m_count; //number of shapes
static unsigned idx; //number of pictures created for debug
public:
Picture(const Point& p1 = 0, color c = White) : Shape(p1, c, picture), m_count(0){ idx++; }
//...
~Picture();
};
In the ~Picture() function, you do the following:
Picture::~Picture()
{
for (int i = 0; i < m_count; i++){
if (m_shapes[i])
delete m_shapes[i];
}
if (m_shapes) // This may not have been initialized!!
delete m_shapes;
}
In the Picture() constructor, you failed to initialize m_shapes, thus a simple one line program would be able to invoke the undefined behavior of calling delete on an uninitialized pointer.
Example:
int main()
{
Picture p(Picture(Point(0, 0), GenC()));
} // The `p` destructor will invoke undefined behavior.
Therefore the immediate fix is to go back and make sure m_shapes is initialized to (at least) a nullptr on construction of Picture.
However the ultimate fix is to start to use std::vector and other containers, in addition to using smart pointers such as std::shared_ptr<Shape> and/or std::unique_ptr<Shape>. When you do this, functions such as Picture::insert_shape become either obsolete, or are simple one-line functions issuing a call to (for example) std::vector<Shape*>::push_back().
For example (using a vector of raw pointers)
#include <vector>
class Picture
{
//...
std::vector<Shape *> m_shapes;
void insert_shape(Shape* s);
//...
};
void Picture::insert_shape(Shape* s)
{
m_shapes.push_back(s);
}
If you want to debug the crash in C++ code, let me show you how to use and inspect dumps:
Use adplus.exe (get it from Microsoft) and run your app in process monitor mode
Download WinDBG (also from Microsoft)
Use the following command to create a dump in monitor mode of your process
ADPlus -Crash -pmn Geometry.exe -o C:\CrashDumps
Open the crash dump in WinDBG
Learn the power of WinDBG
A note: You might need symbols (.pdb) files to be created/loaded in your dump inspection
The error is in this line.
Picture *main_pic = new Picture(Point(0, 0), GenC());
You're not giving the size to your Picture pointer and you're deleting it like an array, You must assign a size to your pointer then you also can delete is like this.
delete [] main_pic;

Reading from vectors C++

What is wrong with this code? It detects whether I've reached the coordinates of a monster but only one of them, or the closest one at least. If I travel to other coordinates it doesn't tell me the monster has appeared. Don't know why because I am looping through the monster vector every time I type 'north'.
Here is the code.
Monster Class:
class Monster
{
public:
std::vector<std::string> names;
std::vector<double> posx; // North - South
std::vector<double> posy; // East - West
bool compareCoords(double monsterPosX, double monsterPosY);
void cMonster(std::string monsterName, double monsterPosX, double monsterPosY);
void randomSpawn();
protected:
private:
};
compareCoords to detect whether a monster already exists at those coordinates and the cMonster (create monster) functions:
void Monster::cMonster(std::string monsterName, double monsterPosX, double monsterPosY)
{
if (compareCoords(monsterPosX, monsterPosY) == false)
{
names.push_back(monsterName);
posx.push_back(monsterPosX);
posy.push_back(monsterPosY);
std::cout << "Monster " << monsterName << " has been created at X: " << monsterPosX << " Y: " << monsterPosY << std::endl;
}
}
bool Monster::compareCoords(double monsterPosX, double monsterPosY)
{
for (unsigned int i = 0; i < posx.size(); i++)
{
if (monsterPosX == posx[i] && monsterPosY == posy[i])
{
return true;
}
}
return false;
}
Main:
int main()
{
srand(time(0));
Monster newenemy;
Character newplayer;
newenemy.cMonster("Weezo", 1, 0);
newenemy.cMonster("Weezo", 2, 0);
newplayer.posx.push_back(0);
newplayer.posy.push_back(0);
home:
std::cout << "-->> ";
std::string userInput;
std::cin.clear();
getline(std::cin, userInput);
if (!userInput.compare("north"))
{
newplayer.headNorth();
for (unsigned int i = 0; i < newenemy.names.size(); i++)
{
if (newplayer.posx[i] == newenemy.posx[i] && newplayer.posy[i] == newenemy.posy[i])
{
std::cout << "A " << newenemy.names[i] << " has appeared." << std::endl;
}
}
}
else if (!userInput.compare("south"))
{
newplayer.headSouth();
for (unsigned int i = 0; i < newenemy.posx.size(); i++)
{
if (newplayer.posx[i] == newenemy.posx[i] && newplayer.posy[i] == newenemy.posy[i])
{
std::cout << "A " << newenemy.names[i] << " has appeared." << std::endl;
}
}
}
else
{
std::cout << "You have entered an invalid command." << std::endl;
}
}
^ As you can see here, it shows when I'm at the coordinates of Gorilla but not the second monster, Donald Trump. It just ignores the second one.
I've been stuck here for hours, I don't understand what could be wrong. Thank you!

delete array pointers heap corruption

I get an exception on this line in Visual Studio 2015. It builds with no errors.
_free_dbg(block, _UNKNOWN_BLOCK);
This is how I declare the new array of pointers:
CAirship * pAirShip[10];
This is how I delete the array of pAirShip pointers:
for (int i = 0; i < 10; i++) {
if (pAirShip[i]) {
cout << "pAirShip[" << i << "] is " << pAirShip[i] << endl;
delete pAirShip[i];// Delete appropriate object
}
} // end for loop
I get an error on attempting to delete pAirShip[0],
Here is a debug window that does print the pointer addresses:
Here is the full code:
struct AirShipFile {
int Type; // Airplane or Balloon
string name; // Name of the airship
int passCount; // passenger count
int weightCargo; // cargo weight
int EngOrGas; // engine or gas type
int distance; // range or altitude
};
enum EngineType { Jet, Propeller }; // for airplanes only
std::ostream& operator<<(std::ostream& out, const EngineType value) {
static std::map<EngineType, std::string> strings;
if (strings.size() == 0) {
#define INSERT_ELEMENT(p) strings[p] = #p
INSERT_ELEMENT(Jet);
INSERT_ELEMENT(Propeller);
#undef INSERT_ELEMENT
}
return out << strings[value];
}
enum GasType {Helium, Hydrogen }; // for proprellers only
std::ostream& operator<<(std::ostream& out, const GasType value) {
static std::map<GasType, std::string> strings;
if (strings.size() == 0) {
#define INSERT_ELEMENT(p) strings[p] = #p
INSERT_ELEMENT(Helium);
INSERT_ELEMENT(Hydrogen);
#undef INSERT_ELEMENT
}
return out << strings[value];
}
enum AirShipType { AIRPLANE, BALLOON };
class CAirship {
public:
CAirship() { }
virtual void SetData(AirShipFile &data) = 0;
virtual void GetData() = 0;
AirShipType GetAirShipType() { return m_AirShipType; }
protected:
AirShipType m_AirShipType;
};
class CAIRPLANE : public virtual CAirship {
public:
CAIRPLANE() : CAirship() {}
void SetData(AirShipFile &data);
void GetData();
private:
EngineType m_EngineType;
int m_MaxPassengerCount;
string m_Name;
int m_MaxCargoWeight;
int m_MaxAltitude;
};
// Function: SetData
void CAIRPLANE::SetData(AirShipFile &data)
{
// cast integer to enum
m_EngineType = EngineType(data.EngOrGas);
// airplane name
m_Name = data.name;
// passenger count
m_MaxPassengerCount = data.passCount;
//max cargo weight
m_MaxCargoWeight = data.weightCargo;
// cast integer to enum
m_AirShipType = AirShipType(data.Type);
// maximum altitude
m_MaxAltitude = data.distance;
}
void CAIRPLANE::GetData()
{
cout << setw(20) << m_Name << "\t" << setw(20) << m_EngineType << setw(20);
cout << left << setw(20) << m_MaxAltitude << "\n";
}
class CBALLOON : public virtual CAirship {
public:
CBALLOON() : CAirship() {}
void SetData(AirShipFile &data);
void GetData();
private:
GasType m_GasType;
EngineType m_EngineType;
int m_MaxPassengerCount;
string m_Name ;
int m_MaxCargoWeight;
int m_MaxAltitude;
};
void CBALLOON::SetData(AirShipFile &data)
{
// cast integer to enum
m_GasType = GasType(data.EngOrGas);
// airplane name
m_Name = data.name;
// passenger count
m_MaxPassengerCount = data.passCount;
//max cargo weight
m_MaxCargoWeight = data.weightCargo;
// cast integer to enum
m_AirShipType = AirShipType(data.Type);
// maximum altitude
m_MaxAltitude = data.distance;
}
void CBALLOON::GetData()
{
cout << setw(20) << m_Name << "\t" << setw(20)<< m_GasType << setw(20);
cout << left << setw(20) << m_MaxAltitude << "\n";
}
// AIRPLANE = 0
// BALLOON = 1
int main(int argc, char *argv[])
{
if (argc != 2) {
cout << "Usage: PR <filename>\n";
return 1;
}
ifstream Infile(argv[1]);
if (!Infile) {
cout << "Cannot open file\n";
return 1;
}
char LineBuf[100];
char d[] = ",";
CAirship * pAirShip[10];
int i = 0;
while (Infile.getline(LineBuf, 100)) {
struct AirShipFile data;
// read the first field Airship type
// airplane or balloon
data.Type = atoi(strtok(LineBuf, d));
switch (data.Type) {
case AIRPLANE:
// Create AIRPLANE Object
pAirShip[i] = new CAIRPLANE();
data.name = strtok(NULL, d);
data.passCount = atoi(strtok(NULL, d));
data.weightCargo = atoi(strtok(NULL, d));
data.EngOrGas = atoi(strtok(NULL, d));
data.distance = atoi(strtok(NULL, d));
break;
case BALLOON:
// Create BALLOON Object
pAirShip[i] = new CBALLOON();
data.name = strtok(NULL, d);
data.passCount = atoi(strtok(NULL, d));
data.weightCargo = atoi(strtok(NULL, d));
data.EngOrGas = atoi(strtok(NULL, d));
data.distance = atoi(strtok(NULL, d));
break;
default:
break;
} // end switch
// call appropriate function
pAirShip[i++]->SetData(data);
memset(LineBuf, '\0', 100);
}
Infile.close();
cout << "Listing of all Airplanes \n";
cout << left << setw(20) << "\nName" << left<< setw(20)<<"\tEngine Type";
cout << left<<setw(20)<<"\Maximum Range" << "\n\n";
for (int i = 0; i < 10; i++) {
if (pAirShip[i]->GetAirShipType() == AIRPLANE)
pAirShip[i]->GetData();
}
cout << "\n\nListing of all Balloons \n";
cout <<left << setw(20) << "\nName" << left << setw(20) << "\tGas Type" ;
cout << left << setw(20) << "\Maximum Altitude" << "\n\n";
for (int i = 0; i < 10; i++) {
if (pAirShip[i]->GetAirShipType() == BALLOON)
pAirShip[i]->GetData();
}
for (int i = 0; i < 10; i++) {
if (pAirShip[i]) {
delete pAirShip[i];// Delete appropriate object
}
} // end for loop
return 0;
}
The problem is that when allocating an array of any kind, C++ does not initialize the elements, but leaves them with "random" values. So, when you create an array of pointers, the pointers are not created with NULL, nullptr or 0 value, so this is not a good indicator if they are really unused on its own. Trying to free the space that isn't allocated is what generates the error. You should first initialize them (by yourself in a for loop) with nullptr right after you create the array, then you can use your code for deleting the array of pointers.

Constructor with a array type of another class

This is the photo of the model I have to resolve:
I have this class:
#include<iostream>
#include<fstream>
using namespace std;
class Word
{
protected:
char *value;
char type[20];
int noChars;
static int noWords;
public:
Word(char *value, char *type)
{
this->noChars = 0;
this->value = new char[strlen(value) + 1];
strcpy(this->value, value);
strcpy(this->type, type);
Word::noWords++;
}
Word()
{
this->noChars = NULL;
this->value = NULL;
strcpy(this->type,"Nedeterminat");
}
void operator=(Word &x)
{
this->noChars = x.noChars;
strcpy(this->type, x.type);
this->value = new char[strlen(x.value) + 1];
strcpy(this->value, x.value);
}
Word(const Word& x){
this->noChars = x.noChars;
strcpy(this->type, x.type);
this->value = new char[strlen(x.value) + 1];
strcpy(this->value, x.value);
}
char* getValue()
{
return this->value;
}
void setType(char* x)
{
if (x == NULL)
{
throw new exception("Tip gresit!");
}
else
{
strcpy(this->type, x);
}
}
char &operator[](int i)
{
if (i >= 0 && i <= (strlen(this->value) - 1))
{
return this->value[i];
}
else
cout << endl << "Eroare indice: " << i;
}
static int getNoWords()
{
return Word::noWords;
}
operator int()
{
return this->noChars;
}
friend ostream& operator<<(ostream&, Word&);
friend istream& operator>>(istream&, Word&);
};
ostream& operator<<(ostream& consola, Word& x)
{
consola << "Value: " << x.getValue() << endl;
consola << "Type: " << x.type << endl;
consola << "NoChars: " << x.noChars << endl;
return consola;
}
istream& operator>>(istream& consola, Word& x){
cout << "Value: "; consola >> x.value;
cout << "Type: "; consola >> x.type;
cout << "NoChars: "; consola >> x.noChars;
return consola;
}
int Word::noWords = 0;
class Dictionary{
private:
char *language;
int noWords;
bool isOnline;
Word v[100];
public:
Dictionary(char *language, Word w, int noWords, bool isOnline)
{
this->language = new char[strlen(language) + 1];
strcpy(this->language, language);
for (int i = 0; i < 100; i++)
{
this->v[i] = w;
}
this->noWords = noWords;
this->isOnline = isOnline;
}
};
int main()
{
//1
Word w1("exam", "noun");
/*Word w2;*/
Word w3 = w1;
cout << w3;
//2
cout << endl << "Word value: " << w3.getValue();
Word w2("to take", "noun");
w2.setType("verb");
//3
w3 = w2;
cout << endl << w3;
Word *pw = new Word("pointer", "noun");
delete pw;
//4
cin >> w3; cout << w3;
char character = w3[2];
cout << endl << character;
//5
double noChars = (int)w1;
cout << endl << noChars;
cout << endl << Word::getNoWords() << endl;
//6
Dictionary dictionary1("English", NULL, 0, false);
}
I have this main:
Dictionary dictionary1("English", NULL, 0, false);
How should I change the constructor to work? I receive a error :
Arrgument types are:(const char[8],int,int,bool);
And how should I write the default constructor?
NULL cannot be assigned to Word. Try Word() instead which will call the default constructor to Word. Consider changing that function parameter to const Word& - anonymous temporaries are allowed to bind to const references.
I'd prefer to see a std::string as the type for the member variable language; using a const std::string& as the function parameter. Then you will not have to worry about a subsequent delete call, and defining your own assignment operators and copy constructors. Currently, your class leaks memory.
You can not Assign null to the type Word. If you want to default it you should pass something like word()
Dictionary dictionary1("English", word(), 0, false);
EDIT:
The better approach,IMO, that will work for the same main() you have is like this:
class Dictionary{
private:
std::string language;
int noWords;
bool isOnline;
std::array<Word,100> v;
public:
Dictionary(std::string const& language, Word* w, int noWords, bool isOnline): language (language),isOnline(isOnline ),noWords(noWords)
{
for (int i = 0; i < 100; i++){
this->v[i] = (w==NULL)?word():*w;
}
}
};