Search code examples
c++memoryglibc

c++ memory error ("double free or corruption") when explicitly calling destructor


I'm having the "*** glibc detected *** /home/ubuntu[....] : double free or corruption (fasttop) : 0x09851168 ***" problem.

Debugging I figured out the line that seems to be the source of the problem:

data[i]->~Class();

which refers to

 class Class {
public:
    Class();
    Class(char *name, double value);
    virtual ~Class();
    char *name;
    double value;
private:

};

then

    Class::Class() {
}

Class::Class(char* name, double value){
    this->name = new char[std::strlen(name)];
    std::strcpy(this->name, name);
    this->value = value;
}

Class::~Class() {
    delete name;
}

now, obviously I'm doing something wrong there. Anyone can tell me what?


Solution

  • I know of only a couple circumstances under which you use: data[i]->~Class();. One is that you're using placement new to create an object at that location. The other is that you're re-initializing an object by destroying it, to be followed immediately by using placement new to create a new object there. Both of these are fairly advanced techniques, and quite frankly, rather unusual except if you're creating a collection class of your own.

    My guess is that 1) you don't need that, and 2) you haven't really shown us the code that matters (which is mostly likely the stuff surrounding the explicit dtor call).

    You do have one other minor problem from allocating name with new[], and deleting it with delete name; -- the two should match up, so you should be using delete [] name;. Given that this is an array of char, however, that's mostly a technicality -- it almost certainly won't cause a problem in this case. If it was an array of objects that had non-trivial destructors, the typical symptom would be that some (most) of the objects didn't get properly destroyed (i.e., their destructors wouldn't get invoked). In theory it's just undefined behavior, so anything could happen, but the real chances of it being the source of your problem are extremely remote (especially, as I said, in the case of an array of char).

    Of course, what you really should do is make name a std::string and skip all that nonsense completely anyway.