I have a class called Myclass
. In the main function, I have created an array object for this class. Whenever I try to delete this dynamically allocated array, the visual studio will say, Error: Debug Assertion Failed!. Expression: is_block_type_valid(header->_block_use)
. Can you please tell me what is causing this or show me an example of fixing this issue.
#include <iostream>
using namespace std;
class Myclass
{
public:
void print()
{
cout << "Hello from Myclass" << endl;
}
};
int main()
{
Myclass *obj[3] = { new Myclass, new Myclass, new Myclass };
// Call each object's print function.
for (int index=0; index < 3; index )
{
obj[index]->print();
}
delete[] obj; //Error
return 0;
}
CodePudding user response:
This:
Myclass *obj[3] = { new Myclass, new Myclass, new Myclass };
is not a dynamically allocated array. It is an array with automatic storage, holding pointers to dynamically allocated objects. To properly clean up, you need:
delete obj[0];
delete obj[1];
delete obj[2];
Because every new
must be matched with a delete
, and you can only delete via delete[]
something that was allocated via new[]
.
There is no need for any dynamic allocation here, just do:
Myclass obj[3] = {};
CodePudding user response:
The delete[]
operator should only be used for arrays created using the new[]
operator, which your obj
isn't. You have a fixed array of pointers to objects, each of which must be deleted as such:
for (int index=0; index < 3; index )
{
delete obj[index];
}
Alternatively, you can create your object array using the new[]
operator, then delete the array with delete[]
:
int main()
{
Myclass* obj = new Myclass[3];
// Call each object's print function.
for (int index = 0; index < 3; index ) {
obj[index].print(); // Note: Use "." here, not "->"
}
delete[] obj;
return 0;
}
CodePudding user response:
The variable obj
is declared as an array with automatic storage duration with the element type Myclass *
.
Myclass *obj[3] = { new Myclass, new Myclass, new Myclass };
That is it is an array of pointers not a pointer.
Each element of the array is indeed a pointer that points to a dynamically allocated memory. So as the array contains three elements you need to call the operator delete
three times for each element.
It is simpler to do that in the range-based for loop.
For example
for ( auto &item : obj )
{
delete item;
item = nullptr;
}
CodePudding user response:
I think you allocated the array wrong.
You should write Myclass* obj = new Myclass[3];
CodePudding user response:
The above answer is perfect. I would only add this is not a good style code, if you "think in C ". This is a rather C style code. First of all, when you are coding in C and is not obligued to use C-compatible code, be cautious whenever you see yourself using a C pointer. In this case, if instead of using a C array of C pointers, you had used a std::vector of MyClass objects, the vector destructor would have called your class destructor for each element, which I think is what you wanted. My suggestion: change the C array to std::vector and you will be happier. Look how you could have implemented it, using C 11 features and forgetting old C stuff:
#include <iostream>
using namespace std;
#include <vector>
class Myclass
{
public:
void print()
{
cout << "Hello from Myclass" << endl;
}
};
int main()
{
cout<<"Hello World" << endl;
vector<Myclass> obj(3);
// Call each object's print function.
for (auto instance : obj)
{
instance.print();
}
return 0;
}
In this case you don't even need to worry about deleting the objects, since the vector destructor will be called when the function goes out of scope, and it will take care of calling Myobjects' destructors. Much cleaner and safer code.
Or, in case performance is a very bottleneck for you and you need a static array, if you are using C 11 or later, you also can use std::array, a less "wild" option (https://en.cppreference.com/w/cpp/container/array).
So that is the tip I leave for you, if coding in C , use the best this language can offer, and try to forget dangerous and wild old C features. C is good as a lightweight and simpler language, when you need it. But everyone knows it is dangerous (and you have just stumbled on it). This book of the Bjarne focuses on teaching C from scratch, leaving behind the not always productive C legacy: Programming: Principles and Practice Using C