views:

231

answers:

3

Hello

What is "minimal framework" (necessary methods) of object, which I will store in STL <vector>?

For my assumptions:

#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, http://stackoverflow.com/users/140719/sbi

+7  A: 

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=(const DoIt& rhs) 
                                   {DoIt tmp(rhs); swap(rhs); return *this;}
};
sbi
Can you provide the code of copy constructor and assignment operator for my case?
osgx
@osgx: I have added the code.
sbi
I think you're missing a colon after the Doit() constructor
AshleysBrain
@AshleysBrain; Thanks. I fixed it.
sbi
@AshleysBrain, nope Doit() a(new char[10]) {} seems perfectly legal to me. If it was without the {} then I would agree with you.
Konrad
@Konrad: `Doit() a(new char[10]) {}` certainly missed a `:`. I fixed this.
sbi
@sbi, not to nit-pick (but I will anyway), but shouldn't operator= be implemented as `DoIt tmp(rhs); swap(tmp); return *this;`
Glen
Not `Doit() : a(new char[10] () ) { }` ?
MSalters
@sbi whoops! Wood for trees.
Konrad
@Glen, please, don't blame sbi. He showed me an idea, and this code was written in the answer form without compiling. But I get the idea, and typos are fixed in question update.
osgx
@osgx, no one's blaming anyone for anything. Clarifications like this are designed to help the person who asked the question, in this case you, get the best possible answer.
Glen
@Glen: You're certainly right. <blush> Sorry.
sbi
@MSalters: What would this bring? You'd initialize the characters which are likely to be overwritten anyway. However, all this would be moot when `std::vector` would have been used - as would be appropriate for this.
sbi
A: 

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.

Peter Alexander
Copyable != assignable.
anon
+5  A: 

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.

Charles Bailey