Removing an array of objects rising to base pointers

started moving some libraries from msvc to mingw and found really interesting msvc behavior when you want to delete an array for objects with increased interest. Namely, msvc does some sort of dark magic (it seems like it), and the following code runs just fine, however in mingw (4.7.2 (crashes). I believe mingw is working correctly, sleeping.

code:

#include <iostream> class foo{ static int idgen; protected: int id; public: foo(){ id = idgen++; std::cout << "Hello ( foo - "<<id<<")"<<std::endl; } virtual ~foo(){ std::cout << "Bye bye ( foo - "<<id<<")"<<std::endl; }; }; int foo::idgen = 0; class bar: public foo{ double some_data[20]; public: bar(){ std::cout << "Hello ( bar - "<<id<<")"<<std::endl; } ~bar(){ std::cout << "Bye bye ( bar - "<<id<<")"<<std::endl; } }; int main() { const unsigned int size = 2; foo** arr = new foo*[size]; { bar* tmp = new bar[size]; for(int i=0; i<size; i++) { arr[i] = &(tmp[i]); //take address of each object } } delete [] arr[0]; //take address of first object, pointer is same as tmp. This also crashes mingw delete [] arr; } 

Exit msvc 2010

 Hello ( foo - 0) Hello ( bar - 0) Hello ( foo - 1) Hello ( bar - 1) Bye bye ( bar - 1) Bye bye ( foo - 1) Bye bye ( bar - 0) Bye bye ( foo - 0) 

And mingw (crashed on destruction)

 Hello ( foo - 0) Hello ( bar - 0) Hello ( foo - 1) Hello ( bar - 1) 

My question is: what is the right approach to fix this. The current hackfix that I came across included just trying downcast for every possible class and calling the delete operation on the down pointer:

 if(dynamic_cast<bar*>(arr[0]) != 0) delete [] dynamic_cast<bar*>(arr[0]); 

Is there a better approach besides redesigning the library (this is not mine)?

+4
source share
2 answers

In the standard specifications, section 5.3.5, clause 3, regarding the delete operator:

[...] In the second alternative (delete array), if the dynamic type of the object to be deleted is different from its static type, the behavior is undefined.

So, you should not rely on the gentle behavior of Visual C ++ in this case and try to provide the delete array operator with a pointer of the correct type, which basically means dynamic casting in your situation.

You can avoid this problem by using a vector instance to store your ascending objects selected one after another.

+4
source

gcc 4.7.2 does not work even with a simple example here -> ideone.com/z876QX#view_edit_box. Thus, we cannot use virtual destructors if it is an array.

 const unsigned int size = 2; foo* test = new bar[size]; delete[] test; 

However, you leave if you use an array of pointers that will allow you to use delete instead of delete[] .

http://ideone.com/NfbF3n#view_edit_box

 const int size = 5; foo *test[size]; for(int i = 0; i < size; ++i) test[i] = new bar; for(int i = 0; i < size; ++i) delete test[i]; 
+1
source

Source: https://habr.com/ru/post/1481044/


All Articles