Using operator delete for an abstract array that contains abstract elements - delete-operator

I have the following class hierarchy and I encounter a problem when trying to use delete[] b. I get an error while compiling saying " has triggered a breakpoint!".
If I use delete b[0], delete b[1] and so on everything is ok.
Could you help me understand why delete[] is not working? Thank you.
#include <iostream>
using namespace std;
class B {
public:
B(int) { cout << "\nconstr B"; }
virtual ~B() {cout << "\ndestr B"; }
virtual char* f() const = 0;
};
class D1 : virtual public B {
public:
D1() : B(1) { cout << "\nconstr D1"; }
~D1() { cout << "\ndestr D1"; }
char* f() const { return "D1"; }
};
class D2 : virtual public B {
public:
D2() : B(2) { cout << "\nconstr D2"; }
~D2() { cout << "\ndestr D2"; }
char* f() const { return "D2"; }
};
class M : public D1 {
public:
M() : B(3) { cout << "\nconstr M"; }
~M() { cout << "\ndestr M"; }
char* f() const {return "M"; }
};
class X : public M {
public:
X() : B(4) { cout << "\nconstr X\n"; }
~X(){ cout << "\ndestr X"; }
char* f() const { return "X"; }
};
void main() {
B* b[4];
b[0] = new D1;
b[1] = new D2;
b[2] = new M;
b[3] = new X;
for (int i = 0; i < 4; i++)
cout << b[i]->f() << endl;
delete[] b;
}

Related

Check special character in string array using isalpha

So I am trying to take words from a file and save them into a dynamic array, and then print the array sorted alphabetically along with the concordance of each word in the array. I am facing a problem in identifying special characters/ numbers and deleting them from the array. I want to use the isalpha function as it is in the assignment prompt. When I run my code, it works perfectly but special characters and numbers are not eliminated from the array. Any idea on how to do this using isalpha?
#include <iostream>
#include <stream>
#include <iomanip>
#include <cstdlib>
#include <algorithm>
#include <cctype>
#include <string>
using namespace std;
void loadData();
void checkSpecialCharacters(string wordPtr, int size);
void alphabeticalSort(string *wordPtr, int size);
void frequencyCounter(string *wordptr, int size);
int main()
{
loadData();
return 0;
}
void loadData()
{
string fileName;
cout << "This program processes any text file to give you the concordance for each word present, and how many times it appears in the file." << endl;
cout << "Please enter the name of the text file you want to process followed by '.txt': " << endl;
cin >> fileName;
ifstream dataFile(fileName);
if (dataFile.fail())
{
cerr << fileName << " could not be opened." << endl; //error message if file opening fails
exit(-1);
}
string word;
int size = 0;
while (dataFile >> word)
{
size++;
}
dataFile.clear();
dataFile.seekg(0);
string* wordPtr = new string[size];
int ctr = 0;
for (int i = 0; i < size; i++)
{
dataFile >> wordPtr[i];
checkSpecialCharacters(wordPtr[i], size);
std::transform(wordPtr[i].begin(), wordPtr[i].end(), wordPtr[i].begin(), ::tolower);
cout << wordPtr[i] << endl;
}
dataFile.close();
alphabeticalSort(wordPtr, size);
frequencyCounter(wordPtr, size);
delete[] wordPtr;
}
void checkSpecialCharacters(string wordPtr, int size)
{
for (int i = 0; i < size; i++)
{
if (isalpha(wordPtr[i]) == true)
{
for (int j = 0; j < size; j++)
{
wordPtr[j] = wordPtr[j + 1];
cout << wordPtr[j];
}
}
}
}
void alphabeticalSort(string *wordPtr, int size)
{
int i, j;
string temp; //temporary holding variable
for (i = 0; i < (size - 1); i++)
{
for (j = 0; j < (size - 1); j++)
{
if ((wordPtr[j])>(wordPtr[j + 1]))
{
temp = wordPtr[j];
wordPtr[j] = wordPtr[j + 1];
wordPtr[j + 1] = temp;
}
}
}
}
void frequencyCounter(string *wordPtr, int size)
{
string finalFileName;
cout << "Please enter the name of the file that you want to store the concordance in followed by .txt: " << endl;
cin >> finalFileName;
ofstream concordanceFile(finalFileName, ios::out);
if (concordanceFile.fail())
{
cerr << finalFileName << " could not be opened." << endl;
exit(-1);
}
int frequency = 1;
int index = 1;
string element = wordPtr[0];
while (index < size)
{
if (wordPtr[index - 1] == wordPtr[index]) // check if element is equal to previous element
{
frequency++;
index++;
}
else
{
concordanceFile.setf(ios::left);
concordanceFile << setw(10) << element << " " << setw(10) << frequency << endl;
cout.setf(ios::left);
cout << setw(10) << element << " " << setw(10) << frequency << endl;
element = wordPtr[index];
index++;
frequency = 1; //reset frequency
}
}
cout << "Concordance data saved in " << finalFileName << " successfully!" << endl;
}

How can I get my queue in C++ work? Unhandeled Exception: Access violation reading location

I got a problem by implementing a queue in C++. I looked for similar problems, but didn't find anything usefull.
I'm using Visual Studio 2019.
I seperated my program in a Main.cpp, a Queue.h and Queue.cpp, Patient.h and Patient.cpp.
I tried to convert the concept for this from Java to C++, but I just can't find a solution for my function getInfo().
I get an exception like this:
Unhandled exception at 0x7C0EF3BE (ucrtbased.dll) in Queue.exe: 0xC0000005: Access violation reading location 0xE8884D8D.
Would be nice if anyone could help me with my problem and explain what I did wrong.
I'm just a beginner so don't be too harsh on me pls xD
Main.cpp:
#include "Queue.h"
#include "Patient.h"
int main() {
Queue queue;
Patient patient1("Name1");
Patient patient2("Name2");
queue.add(patient1);
queue.add(patient2);
queue.getInfo();
}
Queue.h:
#pragma once
#include <iostream>
#include "Patient.h"
using namespace std;
class Queue {
private:
Patient* beginning;
Patient* end;
int amount;
public:
Queue();
void add(Patient p);
Patient remove();
void getInfo();
};
Queue.cpp:
#include "Queue.h"
Queue::Queue() {
beginning = 0;
end = 0;
amount = 0;
}
void Queue::add(Patient p) {
if (amount == 0) {
beginning = &p;
end = &p;
} else {
end->setFollower(p);
end = &p;
}
amount++;
}
Patient Queue::remove() {
if (amount == 0) {
cout << "You can't remove a patient. The Queue is empty!" << endl;
} else {
*beginning = beginning->getFollower();
amount--;
}
return *beginning;
}
void Queue::getInfo() {
if (amount == 0) {
cout << "The Queue is empty!" << endl;
} else {
cout << "There are " << amount << " Patients in the Queue!" << endl;
cout << "The following list provides all Patients in the Queue-order:" << endl;
beginning->getInfo();
}
}
Patient.h:
#pragma once
#include <iostream>
#include <string>
using namespace std;
class Patient {
private:
string name;
Patient* follower;
string* nameptr;
public:
Patient(string newname);
void setFollower(Patient p);
Patient getFollower();
void getInfo();
};
Patient.cpp:
#include "Patient.h"
Patient::Patient(string newname) {
name = newname;
follower = 0;
nameptr = &name;
}
void Patient::setFollower(Patient p) {
follower = &p;
}
Patient Patient::getFollower() {
return *follower;
}
void Patient::getInfo() {
cout << *nameptr << endl;
if (follower == 0) {
cout << "No follower existing!" << endl;
}
else {
follower->getInfo();
}
cin.get();
}
There are a few places where you mix up passing by value with passing by reference.
To start with, the first problem is here:
void Queue::add(Patient p) {
if (amount == 0) {
beginning = &p;
end = &p;
} else {
end->setFollower(p);
end = &p;
}
amount++;
}
You are passing the value of Patient p rather than a reference to the actual object. To fix this you only need to add an "&" to your functional call like this:
void Queue::add(Patient& p) {
if (amount == 0) {
beginning = &p;
end = &p;
} else {
end->setFollower(p);
end = &p;
}
amount++;
}
Note the "&" in the parameters list. Then you must also update the function header:
class Queue {
private:
Patient* beginning;
Patient* end;
int amount;
public:
Queue();
void add(Patient& p);
Patient remove();
void getInfo();
};
You must also pass by reference for your setFollower function:
void Patient::setFollower(Patient& p) {
follower = &p;
}
and in the header file:
void setFollower(Patient& p);
What you need to know going forward is that in C++ all arguments are passed by value unless you specify passing by reference in the function's parameter list. Here is an article about passing variables to functions if you'd like to read more (https://iq.opengenus.org/call-by-value-vs-call-by-reference-cpp/).

How to use namespace declared and defined in a header file?

I have a header file and a source file
Header.h
namespace na{
int gu = 25;
}
Source.cpp
#include "stdafx.h"
int b = 10;
Basics.cpp
#include "stdafx.h"
#include <iostream>
extern int b;
using namespace std;
using namespace na;
void play(){ static int a = 20;
a = a + 10;
cout << a << "\n";
b = b + 50;
cout << b<<"\n";
//Scout << gupta;
}
int _tmain(int argc, _TCHAR* argv[])
{
extern int f;
play();
play();
play();
play();`enter code here`
getchar();
return 0;
}
It throws the following error:
a namespace with this name does not exist
Adding Header.h solves the problem

why can't I return local variable?

I don't know why c++'s rule says that I can't return local variable?
this simple "max" function totally has no problem;
int max(int a,int b)
{
int maxnum;
if(a>b)maxnum= a;
else maxnum= b;
return maxnum;
}
int main( int argc, char** argv )
{
cout<<max(10,30);
system("PAUSE");
return 0;
}
but, when I want to return local variable as before in opencv,it turns out wrong data
why can't I return local variable here?
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <sstream>
using namespace cv;
using namespace std;
Mat GetIntensity(Mat *pic,int y,int x)
{
float Array[6];
for(int i=0;i<6;i++)
{
Array[i]=pic[i].at<uchar>(y,x);
}
Mat Intensity(6,1,CV_32FC1,&Array);
cout<<Intensity;
return Intensity;
}
int main( int argc, char** argv )
{
stringstream ss;
string pic_name;
Mat pic[6];
for(int i=0;i<6;i++)
{
ss.clear();
ss.str(std::string());
ss<<"pic"<<i<<".bmp"<<endl;
ss>>pic_name;
pic[i] = imread(pic_name, CV_LOAD_IMAGE_GRAYSCALE);
if(! pic[i].data )
{// Check for invalid input
cout << "Could not open or find the image" << endl ;
system("pause");
return -1;
}
//namedWindow( pic_name, CV_WINDOW_AUTOSIZE );
// Create a window for display.
//imshow(pic_name, pic[i] );
}
cout<<=GetIntensity(pic,60,60);
system("PAUSE");
//waitKey(0);
return 0;
}
your construct here uses a local array to hold the values. this will get invalid, once your Mat leaves the scope:
Mat GetIntensity(Mat *pic,int y,int x)
{
float Array[6]; //problem
for(int i=0;i<6;i++)
{
Array[i]=pic[i].at<uchar>(y,x);
}
Mat Intensity(6,1,CV_32FC1,&Array); // problem
cout<<Intensity;
return Intensity;
}
better create a Mat with it's own data:
Mat GetIntensity(Mat *pic,int y,int x)
{
Mat Intensity(6,1,CV_32FC1); // no problem
for(int i=0;i<6;i++)
{
Intensity.at<float>(i) = pic[i].at<uchar>(y,x);
}
cout<<Intensity;
return Intensity;
}

Calling a Base Class Construtor in a function of Derived Class

I am trying to call a constructor of a Base Class in a function of Derived Class. Here is the code:
Classes:
#pragma once
#include "CAR_TYRE_DOOR.h"
#include <string>
using namespace std;
//#ifndef 1_A_H_B
//#define 1_A_H_B
class Honda_Civic: public Car
{
private:
string CNG_y_n;
public:
Honda_Civic();
Honda_Civic(string CNG);
Honda_Civic(Honda_Civic& H1);
void set_CNG_y_n(string S);
string get_CNG_y_n();
void print();
};
class BMW: public Car
{
private:
string conv_y_n;
public:
BMW();
BMW(string S);
BMW(BMW& BMW1);
void set_conv_y_n(string S);
string get_conv_y_n();
void print();
};
class Mercedes: public Car
{
private:
int no_WS;
string SGR_y_n;
public:
Mercedes();
Mercedes(int no_WS, string SGR_y_n);
Mercedes(Mercedes& Merc);
//::Car( Merc1);
void set_no_WS(int n);
void set_SGR(string SGR);
int get_no_WS();
string get_SGR();
void print();
};
//#endif
The BaseClass functions:
//#include "BMW+MERC.h"
#include "CAR_TYRE_DOOR.h"
#include "Honda.h"
#include "S_R.h"
#include <iostream>
#include <string>
using namespace std;
void Car::set_color(string S)
{
S = this->color;
}
void Car::set_model(string S)
{
S = this->model;
}
void Car::set_cost(float x)
{
x = this->cost;
}
string Car::get_color()
{
return this->color;
}
string Car::get_model()
{
return this->model;
}
float Car::get_cost()
{
return this->cost;
}
Car::Car()
{
}
Car::Car(string color, string model, float cost)
{
this->color = "white";
this->model = "2011";
this->cost = 1000000;
}
Car::Car(Car& C1)
{
this->color = C1.color;
this->model = C1.model;
this->cost = C1.cost;
for(int i=0; i<4; i++)
{
DX[i] = C1.DX[i];
}
for(int i=0; i<4; i++)
{
TX[i] = C1.TX[i];
}
}
void Car::print_car()
{
cout <<"Car color: "<<get_color()<<endl;
cout <<"Car model: "<<get_model()<<endl;
cout <<"Car door color: "<<DX[0].get_color()<<endl;
cout <<"Car door vendor: "<<DX[0].get_vendor()<<endl;
cout <<"Tyre vendor: "<<TX[0].get_vendor()<<endl;
for(int i=0; i<4; i++)
{
cout <<"Tyre"<< i+1 <<"type: "<<TX[i].get_rubber_type()<<endl;
}
}
The Derived Class:
#include "Honda.h"
#include <iostream>
#include <string>
using namespace std;
Mercedes::Mercedes()
{
}
Mercedes::Mercedes(int no_WS, string SGR_y_n)
{
this->no_WS = 4;
this->SGR_y_n = "Yes";
}
Mercedes::Mercedes(Mercedes& Merc)
{
Mercedes::Car( Merc);
this->no_WS = Merc.no_WS;
this->SGR_y_n = Merc.SGR_y_n;
}
void Mercedes::set_no_WS(int n)
{
this->no_WS = n;
}
void Mercedes::set_SGR(string SGR)
{
this->SGR_y_n = SGR;
}
int Mercedes::get_no_WS()
{
return this->no_WS;
}
string Mercedes::get_SGR()
{
return this->SGR_y_n;
}
void Mercedes::print()
{
Mercedes.print_car();
cout <<"Number of Woofer Speakers: "<<get_no_WS()<<endl;
cout <<"Sunglass Roof: "<<get_SGR()<<endl;
}
Now in the copy constructor of the derivedclass, i am trying to call the copy constructor of the base class using:
Mercedes::Mercedes(Mercedes& Merc)
{
Mercedes::Car( Merc);
this->no_WS = Merc.no_WS;
this->SGR_y_n = Merc.SGR_y_n;
}
See this: Mercedes::Car( Merc);
to implement this, please tell me the syntax.
The proper way to call constructor hierarchies is like this:
class Car
{
public:
Car () { }
Car (cosnt Car &) {}
};
class Mercedes : public Car
{
public:
Mercedes () { }
Mercedes (const Mercedes &) {}
};
Mercedes :: Mercedes () : Car() { }
Mercedes :: Mercedes (const Mercedes &car) : Car(car) { }
A copy constructor looks like this (notice the const):
Class :: Class (const Class &)