Question

What is "minimal framework" (necessary methods) of complex object (with explicitly malloced internal data), which I want to store in STL container, e.g. <vector>?

For my assumptions (example of complex object Doit):

#include <vector>
#include <cstring>
using namespace std;
class Doit {
    private:
        char *a;
    public:
        Doit(){a=(char*)malloc(10);}
        ~Doit(){free(a);}
};

int main(){
    vector<Doit> v(10);
}

gives

*** glibc detected *** ./a.out: double free or corruption (fasttop): 0x0804b008 ***
Aborted

and in valgrind:

malloc/free: 2 allocs, 12 frees, 50 bytes allocated.

UPDATE:

Minimal methods for such object are: (based on sbi answer)

class DoIt{
    private:
        char *a;
    public:
        DoIt() { a=new char[10]; }
        ~DoIt() { delete[] a; }
        DoIt(const DoIt& rhs) { a=new char[10]; std::copy(rhs.a,rhs.a+10,a); }
        DoIt& operator=(const DoIt& rhs) { DoIt tmp(rhs); swap(tmp); return *this;}
        void swap(DoIt& rhs) { std::swap(a,rhs.a); }
};

Thanks, sbi, https://stackoverflow.com/users/140719/sbi

Was it helpful?

Solution

Note that Charles has answered your question perfectly.

Anyway, as per the Rule of Three, your class, having a destructor, should have a copy constructor and an assignment operator, too.

Here's how I would do it:

class Doit {
    private:
        char *a;
    public:
        Doit()                   : a(new char[10]) {}
        ~Doit()                    {delete[] a;}
        DoIt(const DoIt& rhs)    : a(new char[10]) {std::copy(rhs.a,rhs.a+10,a);}
        void swap(DoIt& rhs)       {std::swap(a,rhs.a);}
        DoIt& operator=(DoIt rhs)  {swap(rhs); return *this;}
};

OTHER TIPS

All types that you use must be CopyConstructible and Assignable.

CopyConstructible for a type T means that if t is a T or a const T then the expression T(t) must produce an equivalent T to the original t; t.~T() must be valid (accessible destructor); and &t must give the address of t as a [const] T*.

Assignable means that for a T, t and a T value u, the expression t = u must make t equivalent to u and be of type T&.

Note that all these requirements are met by simple built-in types and POD-structs. If you do anything non-trivial in a destructor or constructor you must ensure that the copy constructor and copy assignment operator preserver the equivalence semantics.

All vector requires is that the object is "assignable", which means that it needs an copy-constructor, destructor, and assignment operator, which are all generated by default if you don't supply them yourself.

As sbi says, if you need one of those functions then you probably need them all. In your case, you'll need to also provide a copy constructor and assignment operator to avoid heap corruption.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top