Reputation: 2645
I've been doing some reading about delete[]
, new[]
, what-is-the-rule-of-three,
deallocating-objects-stored-in-a-vector, delete-vector-class-member and encountering an
Exception thrown: read access violation.
I have defined a base class
class Person
{
private:
std::string name;
int age;
static int cur_id;
public:
Person() {}
Person(std::string new_name, int new_age) : name(new_name), age(new_age) { cur_id += 1; }
virtual ~Person() {}
void setname(std::string name) { this->name = name; }
std::string getname() { return name; }
int getage() { return age; }
void setage(int age) { this->age = age; }
int get_id() { return cur_id; }
virtual void getdata(void) = 0;
virtual void putdata(void) = 0;
};
Derived class
class Professor : private Person
{
private:
int publications;
Professor* prof;
public:
Professor() {}
Professor(std::string new_name, int new_age, int new_pubs) : Person(new_name, new_age) { this->publications = new_pubs; }
~Professor() override { delete prof; }
void getdata() override
{
std::vector<std::string> prof_input = get_input();
std::cout << prof_input[0] << "\n";
std::cout << std::stoi(prof_input[1]) << "\n";
std::cout << std::stoi(prof_input[2]) << "\n";
prof = new Professor(prof_input[0], std::stoi(prof_input[1]), std::stoi(prof_input[2]));
}
void putdata() override
{
std::cout << prof->getname() << " " << prof->getage() << " " << prof->publications << " " << prof->get_id();
}
};
and have defined main
int main()
{
int size;
std::cin >> size;
std::cin.ignore();
Professor* prof = new Professor();
std::vector<Professor> prof_vec;
for (int i = 0; i < size; i++)
{
int which;
std::cin >> which;
std::cin.ignore();
switch (which)
{
case 1:
{
prof->getdata();
prof_vec.push_back(*prof);
}
break;
case 2:
{
// something else
}
break;
}
}
for (auto prof : prof_vec)
{
prof.putdata();
} <<< ------------------- Things so south here
delete prof;
fgetc(stdin);
return 0;
}
What I figured was happening is (assuming only one element in the vector), once the call to putdata()
exited the block, the destructor call delete prof
occurs followed by
this->prof was 0xCDCDCDCD.
I'm attempting to delete an object that doesn't exist. If I want to be sure to properly delete
, what should I be doing to ensure no memory leaks even with such a simple example?
Upvotes: 0
Views: 92
Reputation: 404
The member Professor* prof
is not initialized in the constructor Professor()
, and is only initialized in getdata();
When the code goes to case 2, if there is not any call to getdata()
, then the prof
is left uninitialized.
The 0xCDCDCDCD
indicates an uninitialized value in debug mode.
Upvotes: 2
Reputation: 302852
You're violating the rule of 3/5/0:
class Professor : private Person
{
private:
Professor* prof;
public:
// ...
~Professor() override { delete prof; }
};
If you provide one of the special member functions, you should provide all of the special member functions. In this case, your copy constructor just member-wise copies the Professor*
and now you have two different objects trying to delete the same pointer.
Prefer the rule of 0:
class Professor : private Person
{
private:
std::unique_ptr<Professor> prof;
public:
// ...
~Professor() = default;
};
Upvotes: 4