0

I have an abstract class named Company, a typedef typedef Company* CompanyP; and the following map:

map<string, CompanyP> companies;

When I add companies into the program it's using the insert and make_pair functions, like this:

companies.insert(make_pair(companyName, new Stock(...)));

(Stock's base class is Company)

So as far as I understand the second part of the pair is holding a pointer to this object that i allocated using new, so I should be able to delete it in later part of the code.

So why when I get to the following code in a different function called removeCompany, I get a runtime error? (compList is an array of strings and holds the keys to all existing functions) :

// Delete the company and than delete the pointer from the map
cout << companies.find(compList[cmd - 1])->first << endl;
delete companies.find(compList[cmd-1])->second;
cout << "The company \"" << compList[cmd-1] << "\" has been removed." << endl;
companies.erase(compList[cmd - 1]);

I know that the key is correct using the first line with the cout command because it rightfully shows that the find function indeed finds the correct pair, but when the debugger gets to the delete command I get a runtime error _BLOCK_TYPE_IS_VALID(pHead->nBlockUse).

I've looked into other questions but they were all examples of using the wrong pointers. Here i'm using a base class pointer that points on a derived class, could this be the problem?

asaf92
  • 592
  • 1
  • 10
  • 23
  • 2
    Are the destructors virtual? – Cody Gray Jun 13 '16 at 12:18
  • Is it possible for `cmd-1` to ever resolve to less than zero? Thus `compList[cmd-1]` might be garbage. And does it happen EVERY time, or only sometimes? – Kevin Anderson Jun 13 '16 at 12:19
  • I didn't define any destructors and cmd-1 shows the correct pair so it's not less than zero. – asaf92 Jun 13 '16 at 12:21
  • You must defune a virtual destructir for the base class – n. 'pronouns' m. Jun 13 '16 at 12:22
  • Why? It will just be an empty function, I have no use for destructors. – asaf92 Jun 13 '16 at 12:22
  • Your class has no members that need to be destroyed? – NathanOliver Jun 13 '16 at 12:23
  • 4
    *I didn't define any destructors* -- Thus the error. Calling delete on a base class pointer that points to a derived class is undefined behavior if the base class does not have virtual destructor. – PaulMcKenzie Jun 13 '16 at 12:23
  • No. none of them were dynamically allocated. – asaf92 Jun 13 '16 at 12:23
  • 1
    So why are you calling `delete` on non-dynamically allocated objects? – PaulMcKenzie Jun 13 '16 at 12:24
  • @PanthersFan92 That does not matter. The destructor still needs to be called so the destructors of the automatic objects can be called. If the derived class destructor is not called then you do not cleanup the object correctly. – NathanOliver Jun 13 '16 at 12:25
  • @PaulMcKenzie I did dynamically allocate the object itself using `new` as explained in the question – asaf92 Jun 13 '16 at 12:26
  • @NathanOliver I don't understand. Say I have a class called `base`, so I need to write `virtual ~Base() { ;}` and in every derived class use `~Base() { ; } // Override` ? Like this? Isn't the default destructor defined by default if you don't implement it anyway? – asaf92 Jun 13 '16 at 12:28
  • @PanthersFan92 You just need to declare it in the base class like `virtual ~base(){}` or `virtual ~base() = default;` – NathanOliver Jun 13 '16 at 12:30
  • If you want polymorphic deletion, you need a virtual destructor. Hard requirement. The linked duplicate contains a detailed explanation. It does not matter that you write not code in the destructor. The compiler does. – Cody Gray Jun 13 '16 at 12:31
  • Good Link Cody, but I would add on to this for PanthersFan that even if you're not allocating anything with `new` in the base class OR the derived class, and only have "automatic" members, you still need the base and derived destructors to be virtual. This is the point he seems to not understand and/or object to. – Kevin Anderson Jun 13 '16 at 12:48
  • I understand now that I need to make them virtual, I don't understand how is that useful or why is it mandatory. I will check the link that Cody gave, thanks. – asaf92 Jun 13 '16 at 12:56
  • @PanthersFan92 It is mandatory because that's the way the language works. Again, you are deleting a derived class object through a base class pointer. The mechanism that is used in C++ to say "I'm not really a base, I'm a derived so start deleting me from the derived object" is to make the destructor virtual in the base class. – PaulMcKenzie Jun 13 '16 at 15:01

0 Answers0