C++ destroying base class causes debug assertion failed - c++

I'm trying to learn a bit more about polymorphism and I tried to make it as simple as possible, so I got base class Figure and 2 derived classes Rectangle and Circle.
class Figure {
public:
Figure() { cout << "Creating Figure\n"; }
virtual ~Figure() { cout << "Destroying Figure\n"; }
virtual double calculateField() {
return 0;
}
};
class Rectangle : public Figure
{
public:
Rectangle(double m_a) : p_a(m_a) { cout << "Creating Rectangle\n"; }
~Rectangle() { cout << "Destroying Rectangle\n"; }
virtual double calculateField() {
return p_a*p_a;
}
private:
double p_a;
};
class Circle : public Figure
{
public:
Circle(double m_r) : p_r(m_r) { cout << "Creating Circle\n"; }
~Circle() { cout << "Destroying Circle\n"; }
virtual double calculateField() {
return p_r*3.14*3.14;
}
private:
double p_r;
};
In main function I create pointer to Figure class and 2 objects - rectangle and circle. Then I set Figure pointer on 1 of them and call calculateField() on this pointer. It works. But at the end I try to call delete on this pointer and it crashes my program.
int main(){
Figure *ptr = new Figure();
Rectangle rec(5);
Circle circ(5);
cout << "Figure field: " << ptr->calculateField() << endl;
ptr = &rec;
cout << "Rectangle field: " << ptr->calculateField() << endl;
ptr = ˆ
cout << "Circle field: " << ptr->calculateField() << endl;
delete ptr;
cin.get();
return 0;
}
Result of this looks like this:
Creating Figure Creating Figure Creating Rectangle
Creating Figure Creating Circle Figure field: 0 Rectangle
field: 25 Circle field: 49.298 Destroying Circle
Destroying Figure
But then I got Debug Assertion Failed
Expression: _BLOCK_TYPE_IS_VALID(pHead -> nBlockUse)

The program behaviour is undefined.
You can only call delete on the pointer you get back from new.
Currently you're trying to delete something that has automatic storage duration. That is never going to end well.

You actually create a simple Figure at Figure *ptr = new Figure();, but, you immediately leak it by re-using ptr in ptr = &rec;
And just before calling delete you once again re-used the pointer in ptr = ˆ, so in fact you are calling:
delete ˆ
which is obviously an error.
In fact, everything will be correct provided you never use ptr in new or delete but a different pointer:
Figure *ptr, *ptr2 = new Figure();
...
delete ptr2;

Related

How to implement classes derived from an abstract with different methods?

I have implemented different classes derived from an abstract class and each one has different methods. The problem is that I have to declare the object only at runtime, so I have to create a pointer to the base class and I can't use the methods of each derived class.
I have created an example to explain better what I mean:
#include <iostream>
using namespace std;
class poligon
{
public:
double h, l;
void setPoligon(double h, double l) {
this->h = h;
this->l = l;
}
virtual double GetArea() = 0;
virtual void GetType() = 0;
};
class triangle : public poligon
{
double GetArea() { return l*h / 2; }
void GetType() { cout << "triangle" << endl; }
double GetDiag() { return sqrt(l*l + h*h); }
};
class rectangle : public poligon
{
double GetArea() { return l*h; }
void GetType() { cout << "rectangle" << endl; }
};
void main()
{
poligon* X;
int input;
cout << "1 for triangle and 2 for rectangle: ";
cin >> input;
if (input == 1)
{
X = new triangle;
}
else if (input == 2)
{
X = new rectangle;
}
else
{
cout << "Error";
}
X->h = 5;
X->l = 6;
X->GetType();
cout << "Area = " << X->GetArea() << endl;
if (input == 2)
{
cout << "Diangonal = " << X->GetDiag() << endl; // NOT POSSIBLE BECAUSE " GetDiag()" IS NOT A METHOD OF "poligon" CLASS !!!
}
}
Obviously the method X->GetDiag() at the end of the main can't be used because it is not a method of the "poligon" class.
Which is the correct implementation of a program with this logic?
Introduce a method in the base class
virtual bool boHasDiagonal(void) =0;
Declare unconditionally in base class:
virtual double GetDiag();
Implement it differently in both derived classes:
virtual bool boHasDiagonal(void) {return true;} // rectangle
virtual bool boHasDiagonal(void) {return false;} // triangle
Change output line:
if (X->boHasDiagonal())
{cout << "Diangonal = " << X->GetDiag() << endl;}
For a nice touch of paranoia (a healthy state of mind for a programmer in my opinion), use concept by Gluttton of a default implementation of GetDiag(), which signals an error (as in his answer here) .
For the case of many poligons, I like the proposal by Rakete1111 in the comment.
Define method in the base class which define implementation throws exception:
class poligon
{
public:
virtual double GetDiag()
{
throw std::logic_error ("Called function with inappropriate default implementation.");
}
};
In class that has meaningful implementation override it:
class rectangle : public poligon
{
double GetDiag() override
{
return diagonale;
}
};
Usage:
int main () {
try {
X->GetDiag();
}
catch (...) {
std::cout << "Looks like polygon doesn't have diagonal." << std::endl;
}
}
You can use dynamic_cast.
dynamic_cast<triangle*>(X)->GetDiag();
Note that you already have a bug: You only create a triangle if input == 1, but you get the diagonal if input == 2. Also, the above is not really safe, because dynamic_cast can return nullptr if the conversion is invalid.
But it would be better to check whether dynamic_cast succeeds, then you could also drop the input == 2 check:
if (triangle* tri = dynamic_cast<triangle*>(X))
std::cout << "Diagonal = " << tri->GetDiag() << '\n';
Use dynamic casting to check if the base class' pointer is actually a triangle, like this:
int main()
{
...
if(triangle* t = dynamic_cast<triangle*>(X))
std::cout << "Triangle's diagonal = " << t->GetDiag() << std::endl;
return 0;
}
PS: I assume that your example is just a draft, since it has some bugs.
You use dynamic_cast to access subclass-methods.
It returns nullptr if it is not derived from the class. This is called down cast, as you are going down the class-tree:
triangle* R = dynamic_cast<triangle*>(X);
if(R) {
cout << "Diagonale = " << R->GetDiag() << '\n';
};
Edit: You can put the declaration in the first line into the if-condition, which goes out of scope outside the if-statement:
if(triangle* R = dynamic_cast<triangle*>(X)) {
cout << "Diagonale = " << R->GetDiag() << '\n';
};
if(rectangle* R = ...) {...}; // reuse of identifier
If you want to allow, that multiple subclasses have the GetDiag function you can inherit from the poligon-class and another diagonal-class. The diagonal-class only defines the GetDiag function and has not really to do with the polygon-class:
class polygon {
// stays the same
};
class diagonal {
virtual double GetDiag() = 0;
};
class triangle : public polygon, public diagonal {
// body stays the same
};
And like above, you access the methods via casting with dynamic_cast but this time you cast to type diagonal. This time it is side cast, because poligon has nothing to do with diagonal, so you are going sideways in the tree.
polygon diagonal
| | |
| |_____________|
| |
| |
rectangle triangle
As others have said, you can use dynamic_cast to change the static type in your program, add a method to the base-class with a pseudo implementation or use some form of type-switching. However, I would consider all these answers as signs of a design flaw in your program and would reject the code. They all encode assumptions about the types existing in your program into the code and pose a maintenance burden. Imagine adding new types of shapes to your program. You then have to search and modify all the places you dynamic_cast your objects.
I think your example hierarchy is wrong in the first place. When you declare a base-class for ploygons, and derive triangles from it, the whole purpose of polymorphism is to be able to treat similar objects identically. So anything that is not common behavior (not implementation) is put in the base-class.
class poligon
{
public:
double h, l;
void setPoligon(double h, double l) {
this->h = h;
this->l = l;
}
virtual double GetArea() = 0;
virtual void GetType() = 0;
};
class triangle : public poligon
{
double GetArea() { return l*h / 2; }
void GetType() { cout << "triangle" << endl; }
double GetDiag() { return sqrt(l*l + h*h); }
};
You explicitly say that I can replace any instance of polygon with an instance of triangle everywhere in your program. This is the the Liskov substitution principle. What about circles? They don't have height and length. Can you use a rectangle everywhere you expect a polygon? Currently you can, but polygons can have more edges, be self-intersecting etc. I cannot add a new edge to a rectangle, otherwise it would be a rectangle anymore.
There are some solutions, but as it is a design question, the solution depends on what you want to do with the objects.
A downcast is usually a sign of a bad design and is rarely needed in practice.
I can't see why it is needed in this particular case. You have discarded the information about which type you have for no reason. An alternative could be:
void printDiagonal(const triangle& tri)
{
std::cout << "Diangonal = " << tri.GetDiag() << std::endl;
}
void process(poligon& p)
{
p.h = 5;
p.l = 6;
p.GetType();
std::cout << "Area = " << p.GetArea() << std::endl;
}
int main()
{
int input;
std::cout << "1 for triangle and 2 for rectangle: ";
std::cin >> input;
if (input == 1)
{
triangle tri;
process(tri);
printDiagonal(tri);
}
else if (input == 2)
{
rectangle rect;
process(rect);
}
else
{
std::cout << "Error\n";
}
}
Live demo.

Explaining constructor and copy constructor example

I have this code and I can understand what happening with the contractor of class Fat.
#include <iostream>
using namespace std;
class Block{
int data;
public:
Block(int i = 10) : data(i){
cout << "I just created a Block " << endl;
}
~Block() {
cout << "I will destroy a Block with " << data << endl;
}
void inc() {
data++;
}
};
class A{
Block& block1;
Block block2;
public:
A(Block& blk) : block1(blk), block2(blk) {
cout << "I just created an A " << endl;
}
A(const A& a): block1(a.block1), block2(a.block2) {
cout << "I just created an A by copying but I will also do bad things" << endl;
block1.inc(); block2.inc();
}
~A() {
cout << "I will destroy an A " << endl;
}
void inc() {
block1.inc(); block2.inc();
}
};
class Fat{
A a;
A& ra;
A* pa;
public:
Fat(A& da) : a(da),ra(da) {
pa = new A(da);
cout << "Fat just created !" << endl;
}
~Fat() {
delete pa;
cout << "Fat to be destroyed !" << endl;
}
void inc() {
a.inc();
ra.inc();
pa->inc();
}
};
int main(){
Block block;
A a(block);
Fat fat(a);
fat.inc();
return 0;
}
and the result of this :
I just created a Block
I just created an A
I just created an A by copying but I will also do bad things
I just created an A by copying but I will also do bad things
Fat just created !
I will destroy an A
I will destroy a Block with 12
Fat to be destroyed !
I will destroy an A
I will destroy a Block with 12
I will destroy an A
I will destroy a Block with 11
I will destroy a Block with 15
Why does the copy constructor run twice?
The first "I just created an A by copying but I will also do bad things"comes from this line:
Fat(A& da) : a(da), ra(da) {
a(da) this one calls A's copy constructor
the seconds one from the constructer of class fat:
Fat(A& da) : a(da), ra(da) {
pa = new A(da); //HERE!!
cout << "Fat just created !" << endl;
}
again, with pa = new A(da); you call A's copy constructor.
edit: thank you for formatting your code
The first copy is made to initialise the a member variable in Fat:
Fat(A& da) : a(da), ra(da) {
Then the line
pa = new A(da);
creates a new instance of A on the free store by copying da hence it calls the copy constructor. If instead you wanted to make a pointer to an existing instance of A you should write
pa = &da;

Crash Issue - C++ Code Design using pointers and destructors

I have a question regarding the following code, which crashes. I am creating a local variable in testfunction() and then pushing it (variable "y") into a list. This variable has a member pointer "b" of object type Ball. As I understand, this local variable "y" is on the stack, so its' destructor will be called after testfunction() is completed. Also, as I understand, a vector "copies" an object into its' list. From what I've learned, it is best practice to delete a pointer in the destructor if one exists in its' class. So, there is "delete b" in the destructor of Example.
The issue that I am having is that the object y.b is being destroyed at the completion of testfunction(). In main(), I am able to see the value of "name" and the address of "b", but the object "b" has already been deleted. I would like to avoid this.
I think there is an issue with the design of the code/use of pointers vs references, etc. Please guide me in the right direction, I am an idiot!
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Ball
{
public:
int a;
Ball()
{
a = 0;
}
~Ball()
{
cout << "destroyed Ball()" << endl;
}
};
class Example
{
public:
string name;
Ball* b;
Example()
{
name = "";
b = NULL;
}
~Example()
{
cout << "destroying Example()" << endl;
delete b;
}
};
void testfunction(vector<Example>& list)
{
cout << "entered testfunction1()" << endl;
Example y;
y.name = "myName";
y.b = new Ball();
y.b->a = 5;
cout << "y.b->a = " << y.b->a << endl;
list.push_back(y);
cout << "exit testfunction1()" << endl;
}
void testfunction2()
{
cout << "entered testfunction2()" << endl;
Example* y = new Example();
cout << "exit testfunction2()" << endl;
}
int main() {
vector<Example> list;
testfunction(list);
//testfunction2();
if(list[0].b == NULL)
cout << "b is null" << endl;
else
cout << "b is not null" << endl;
cout << list[0].name << endl;
cout << list[0].b << endl;
cout << "list[0].b->a = " << list[0].b->a << endl;
return 0;
}
Since class Example has a pointer member and it tries to own a dynamically allocated resource, it needs non-default copy operations, in other words, it needs user-defined copy constructor and assignment operator.
Inside testfunction, when you copy y into vector, both local y and y copied to the vector point to very same Ball object. The local y is destroyed at the end of the function and Ball is deleted. However, that deleted Ball still pointed by the y in vector
void testfunction(vector<Example>& list)
{
// ...
Example y;
y.name = "myName";
y.b = new Ball();
y.b->a = 5;
list.push_back(y);
// ...
} // <-- destructor for Example y is called and y.b is deleted
Define a copy constructor and an assignement operator for your class Example.
These shall copy properly your object (creating a duplicated Ball object) when pushed back on the vector.
Example(const Example& a)
{
name = a.name; // attention no dynamic allocation
cout << "copy" <<endl;
if (a.b) {
b = new Ball(*a.b); // create a new duplicated Ball
}
else b = NULL;
}
The problem in your example is that the default copy constructor is called when you pushback the object. It copies memberwise and so the pointer to Ball is copied, not the object pointed to.
Yet another alternative could be to replace your Ball* with shared_ptr<Ball> (and accordingly, new Ball with make_shared<Ball>() and the delete b of the object with a b.reset()). The principle is that this smart pointer keeps track of the number of time the object pointed to is used, so that it will not delete it twice, but only when its no longer used anywhere.

C++ - Array of pointers to object, what is stored in STACK and what in HEAP?

I'm very new to C++ and I wish to make clear some points regarding memory management using the operator "new ..." and the operator "delete ...".
I will post some code of mine, and I ask if you please would correct my comments if they are wrong.
I'm also dealing with virtual functions and interface, which is clear by reading the code, and I also ask you if i'm approaching them the right way.
Then I have a more direct question, when should I use "new[] ..." or "delete[] ...", and how should I use them correctly?
PS: the output of code below is:
car built
motorcycle built
car has 4 wheels
motorcycle has 2 wheels
car destroyed
motorcycle destroyed
That's the main.cpp source:
#include <iostream>
using namespace std;
class vehicle
{
public:
virtual
~vehicle()
{
}
virtual void
wheelNum() = 0;
};
class car : public vehicle
{
public:
car()
{
cout << "car built" << endl;
}
~car()
{
cout << "car destroyed" << endl;
}
void
wheelNum()
{
cout << "car has 4 wheels" << endl;
}
};
class motorcycle : public vehicle
{
public:
motorcycle()
{
cout << "motorcycle built" << endl;
}
~motorcycle()
{
cout << "motorcycle destroyed" << endl;
}
void
wheelNum()
{
cout << "motorcycle has 2 wheels" << endl;
}
};
int
main()
{
// motorVehicle[2] is allocated in the STACK and has room for 2 pointers to vehicle class object
// when I call "new ...", I allocate room for an object of vehicle class in the HEAP and I obtain its pointer, which is stored in the STACK
vehicle* motorVehicle[2] = { new (car), new (motorcycle) };
for (int i = 0; i < 2; i++)
{
// for every pointer to a vehicle in the array, I access the method wheelNum() of the pointed object
motorVehicle[i] -> wheelNum();
}
for (int i = 0; i < 2; i++)
{
// given that I allocated vehicles in the HEAP, I have to eliminate them before terminating the program
// nevertheless pointers "motorVehicle[i]" are allocated in the STACK and therefore I don't need to delete them
delete (motorVehicle[i]);
}
return 0;
}
Thanks you all.
Memory allocated with new is on the HEAP, everything else in on the stack. So in your code, you have
vehicle* motorVehicle[2] = { new (car), new (motorcycle) };
On the stack there is an array of two pointers vehicle*[2], and on the heap are two objects, a car and a motocycle.
Then you have two loops
for (int i = 0; i < 2; i++)
each of which create an integer on the stack for the duration of the loop.
Concerning your code: the array of pointers is a local variable,
which would be allocated on the stack. What the pointers them
selves point to is, in the case of your example, allocated
dynamically (on the heap).
Concerning the "more direct question": I've yet to find any case
where new[] should be used. It's present for reasons of
completeness, but it doesn't really have any reasonable use.

Newb C++ Class Problem

I am trying to get a grasp on pointers and their awesomeness as well as a better C++ understanding. I don't know why this wont compile. Please tell me what is wrong? I'm trying to initialize the pointer when an instance of the class is created. If I try with a normal int it works fine but when I tried to set it up with a pointer i get this in the console
Running…
Constructor called
Program received signal: “EXC_BAD_ACCESS”.
sharedlibrary apply-load-rules all
Any assistance is appreciated greatly.
Here is the code
#include <iostream>
using namespace std;
class Agents
{
public:
Agents();
~Agents();
int getTenure();
void setTenure(int tenure);
private:
int * itsTenure;
};
Agents::Agents()
{
cout << "Constructor called \n";
*itsTenure = 0;
}
Agents::~Agents()
{
cout << "Destructor called \n";
}
int Agents::getTenure()
{
return *itsTenure;
}
void Agents::setTenure(int tenure)
{
*itsTenure = tenure;
}
int main()
{
Agents wilson;
cout << "This employees been here " << wilson.getTenure() << " years.\n";
wilson.setTenure(5);
cout << "My mistake they have been here " << wilson.getTenure() <<
" years. Yep the class worked with pointers.\n";
return 0;
}
You don't ever create the int that the pointer points to, so the pointer is pointer to an area of memory that doesn't exist (or is used for something else).
You can use new to get a block of memory from the heap, new returns the address of the memory location.
itsTenure = new int;
So now itsTenure holds the memory location you can dereference it to set its value.
The changed constructor is as follows:
Agents::Agents()
{
cout << "Constructor called \n";
itsTenure = new int;
*itsTenure = 0;
}
But you must also remember to delete it using delete
Agents::~Agents()
{
cout << "Destructor called \n";
delete itsTenure;
}
You are just missing a new, in the constructor.
itsTenure = new int;
You don't need to make this a pointer, however. Why are you?
You have to allocate a block of memory for your int, and only then use the address of this block of memory (the pointer). This is done with new :
cout << "Destructor called \n";
itsTenure = new int;
*itsTenure = 0;
Then you have to release the memory in the destructor with delete:
cout << "Destructor called \n";
delete itsTenur;
*itsTenure = 0 does not initialize the pointer. It writes 0 to the location that itsTenure points to. Since you never specified where itsTenure points to, that might be anywhere and the behaviour is undefined (an access violation like you're getting being the most likely result).
You need to allocate memory for *tenure in the constructor:
Agents::Agents()
{
cout << "Constructor called \n";
itsTenure = new int;
*itsTenure = 0;
}