Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio 2010 C++ runtime error

I came across strange behavior in Visual Studio 2010 C++ compiler. Following code compiles but throws "Debug assertion failed" after execution with message:

"_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)"

Compiles and runs smoothly under GCC. Is it my fault?

#include <iostream>
#include <vector>


using namespace std;

typedef unsigned int uint;


class Foo {
    vector<int*> coll;
public:

    void add(int* item) {
       coll.push_back(item);
    }

    ~Foo() {
        for (uint i = 0; i < coll.size(); ++i) {
            delete coll[i];
            coll[i] = NULL;
        }
    }
};

int main()
{
   Foo foo;
   foo.add(new int(4));
   Foo bar = foo;

   return 0;
}
like image 518
user742010 Avatar asked Dec 17 '22 14:12

user742010


1 Answers

You didn't implement a copy constructor and copy assignment operator (see rule of three). This results in a shallow copy of the pointers in your vector, causing a double delete and the assertion. EDIT: Double delete is undefined behavior so both VS and gcc are correct here, they're allowed to do whatever they want.

Typically when you implement a destructor with non-trivial behavior you'll also need to write or disable copy construction and copy assignment.

However in your case do you really need to store the items by pointer? If not, just store them by value and that would fix the problem. Otherwise if you do need pointers use shared_ptr (from your compiler or boost) instead of raw pointers to save you from needing to write your own destructor/copy methods.

EDIT: A further note about your interface: Interfaces like this that transfer ownership of passed in pointers can cause confusion by people using your class. If someone passed in the address of an int not allocated on the heap then your destructor will still fail. Better is to either accept by value if possible, or clone the passed in item making your own call to new in the add function.

like image 184
Mark B Avatar answered Dec 28 '22 08:12

Mark B