What is the way arround HEAP CORRUPTION DETECTED in my code? I am trying to write a basic program using c++ object oriented programming. My code looks like this:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Plant
{
public:
Plant(void); // Constructor for the Plant class
Plant(const char*); // Overloaded constructor for the Plant class
Plant(Plant&); // Copy constructor for the Plant class
~Plant(void) // Destructor for the Plant class
{
delete kingdom;
}
virtual void print(void); // Virtual function to print information about the Plant
void link(Plant*); // Function to link a Plant object to the current object
void printList(Plant*); // Function to print a list of Plant objects
protected:
char* kingdom; // Pointer to a character array representing the plant kingdom
Plant* next; // Pointer to the next Plant object in the list
};
class Flower : public Plant // Derived class Flower inheriting from the Plant class
{
public:
Flower(const char* r = " division - Angiosperms"); // Constructor for the Flower class
~Flower(void) // Destructor for the Flower class
{
delete division;
}
virtual void print(void); // Virtual function to print information about the Flower
private:
char* division; // Pointer to a character array representing the flower division
};
class ClassFlower : public Flower // Derived class ClassFlower inheriting from the Flower class
{
public:
ClassFlower(const char* v = "Monocotyledons"); // Constructor for the ClassFlower class
~ClassFlower(void) // Destructor for the ClassFlower class
{
delete classFlower;
}
virtual void print(void); // Virtual function to print information about the ClassFlower
private:
char* classFlower; // Pointer to a character array representing the flower class
};
// Definitions of class Plant member functions
Plant::Plant(void)
{
next = 0;
kingdom = new char[30];
strcpy(kingdom, " the most diverse kingdom of species");
}
Plant::Plant(const char* newKingdom)
{
next = 0;
kingdom = new char[strlen(newKingdom) + 1];
strcpy(kingdom, newKingdom);
}
Plant::Plant(Plant& newPlant)
{
next = 0;
kingdom = new char[strlen(newPlant.kingdom) + 1];
strcpy(kingdom, newPlant.kingdom);
}
void Plant::print(void)
{
cout << "The plant kingdom is " << kingdom << "\n";
}
void Plant::link(Plant* pt)
{
pt->next = next;
next = pt;
}
void Plant::printList(Plant* first)
{
for (Plant* np = first; np; np = np->next)
np->print();
}
// Definitions of class Flower member functions
Flower::Flower(const char* r)
{
division = new char[strlen(r) + 1];
strcpy(division, r);
}
void Flower::print(void)
{
cout << "Roses are from" << division << "\n";
}
// Definitions of class ClassFlower member functions
ClassFlower::ClassFlower(const char* r)
{
classFlower = new char[strlen(r) + 1];
strcpy(classFlower, r);
}
void ClassFlower::print(void)
{
Flower::print();
cout << "from class " << classFlower << "\n";
void getch();
}
// main function
void main(void)
{
Plant* p;
Plant* p1;
Plant* a = new Plant; // Create a Plant object using the default constructor
Plant* u = new Flower; // Create a Flower object using the default constructor
Plant* m = new ClassFlower; // Create a ClassFlower object using the default constructor
p = a;
Plant* list = p;
p1 = u;
p->link(p1);
p = p1;
p1 = m;
p->link(p1);
list->printList(list); // Print the list of Plant objects
delete a; // Free the memory for the Plant object
//delete u; // Free the memory for the Flower object
//delete m; // Free the memory for the ClassFlower object
delete p1;
}
I get the error HEAP CORRUPTION DETECTED: after Normal block (#159) at 0x000001F2C954FC30.
It is because I am not sure which object should be deleted at the end of main. I would appriciate any help and guidance since I am a novice at programming.
I tried deleting only a variable, and then all of the pointer variables but the error remains.
I'm going to put this together from my comments. But the gist is that C++ is not C, and you're doing many things (incorrectly) in a C fashion, but the C++ way completely removes the errors for you.
The issue is likely in your linked list code, but I'm not going to bother debugging it, as you should not have integrated it into your
Plantclass. Your code should have a single purpose. If you need aPlantclass, only writePlantcode for it. If you need a linked list, usestd::listfrom<list>. Avoid C-strings and all the headache that comes from managing them manually and usestd::stringfrom<string>. This code does deal with heap memory, but you can avoidnewanddeleteand usestd::unique_ptrfrom<memory>.There are other issues, like your base class destructor not being virtual. And minor nits like leaving
()empty instead of writingvoid. That's a C-ism, and unnecessary in C++.using namespace std;isn't saving that much time or typing, so start learning to stop using it. It will only cause headaches as the code you write gets bigger and more complex.Other nits are less important, but contribute to better styled code. For example,
protectedmember data is a bad idea. Issues with that data could come from any derived class, or the base. The data should be private, and getters and setters should be protected. Issues with the data lie in a single class.And with constructors, make use of the initialization section.
Here is an example of your code with more C++ applied to it. It still uses heap memory, but has zero
news anddeletes because the Standard Library constructs employed do this for you.