Question

I have been looking around at the meaning of this error and it seems to mean that I am freeing the same object more than once. I can't seem to figure out how to prevent this. Any help or suggestions would be much appreciated.

File(randname)
File(a.out)
~File(a.out)
~Directory(randname)
~File(null)
~File()
*** glibc detected *** a.out: double free or corruption (fasttop): 0x0804b048 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6ff0b)[0xb74baf0b]
/usr/local/gcc/gcc-cilk/lib/libstdc++.so.6(_ZdlPv+0x1f)[0xb7671b4f]
/usr/local/gcc/gcc-cilk/lib/libstdc++.so.6(_ZdaPv+0x1b)[0xb7671b9b]
a.out[0x8048983]
a.out[0x8048b12]
a.out[0x80487d7]
/lib/libc.so.6(__libc_start_main+0xf3)[0xb7464003]
a.out[0x8048701]
======= Memory map: ========
08048000-08049000 r-xp 00000000 00:25 268562602  /home/user/test/a.out
08049000-0804a000 r--p 00000000 00:25 268562602  /home/user/test/a.out
0804a000-0804b000 rw-p 00001000 00:25 268562602  /home/user/test/a.out
0804b000-0806c000 rw-p 00000000 00:00 0          [heap]
b7448000-b744b000 rw-p 00000000 00:00 0
b744b000-b75b2000 r-xp 00000000 08:01 1365267    /lib/libc-2.14.1.so
b75b2000-b75b4000 r--p 00167000 08:01 1365267    /lib/libc-2.14.1.so
b75b4000-b75b5000 rw-p 00169000 08:01 1365267    /lib/libc-2.14.1.so
b75b5000-b75b8000 rw-p 00000000 00:00 0
b75b8000-b75d3000 r-xp 00000000 08:01 1179017    /usr/local/gcc/gcc-cilk/lib/libgcc_s.so.1
b75d3000-b75d4000 r--p 0001a000 08:01 1179017    /usr/local/gcc/gcc-cilk/lib/libgcc_s.so.1
b75d4000-b75d5000 rw-p 0001b000 08:01 1179017    /usr/local/gcc/gcc-cilk/lib/libgcc_s.so.1
b75d5000-b75fe000 r-xp 00000000 08:01 1365275    /lib/libm-2.14.1.so
b75fe000-b75ff000 r--p 00028000 08:01 1365275    /lib/libm-2.14.1.so
b75ff000-b7600000 rw-p 00029000 08:01 1365275    /lib/libm-2.14.1.so
b7622000-b7624000 rw-p 00000000 00:00 0
b7624000-b770b000 r-xp 00000000 08:01 1179021    /usr/local/gcc/gcc-cilk/lib/libstdc++.so.6.0.19
b770b000-b770f000 r--p 000e7000 08:01 1179021    /usr/local/gcc/gcc-cilk/lib/libstdc++.so.6.0.19
b770f000-b7710000 rw-p 000eb000 08:01 1179021    /usr/local/gcc/gcc-cilk/lib/libstdc++.so.6.0.19
b7710000-b7718000 rw-p 00000000 00:00 0
b7718000-b7737000 r-xp 00000000 08:01 1365260    /lib/ld-2.14.1.so
b7737000-b7738000 r--p 0001f000 08:01 1365260    /lib/ld-2.14.1.so
b7738000-b7739000 rw-p 00020000 08:01 1365260    /lib/ld-2.14.1.so
bfa18000-bfa39000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
Aborted

And here is the code:

#include <unistd.h>
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

class File
{
protected:
    unsigned char recordLen;
    unsigned location;
    unsigned fileSize;
    unsigned char filenameLen;
    char* filename;

public:
    File(){filename = NULL;}
    File(FILE* readFromHere, const char* name)
    {
        recordLen = 152;
        location = 20003;
        fileSize = 16348;
        filenameLen = strlen(name);
        filename = new char[filenameLen + 1];
        strcpy(filename, name);
        cout << "File(" << filename << ")\n";
    }
    File(const File& o)
    {
        if (o.filename == NULL)
            filename = o.filename;
        else
        {
            filename = new char[o.filenameLen + 1];
            strcpy(filename, o.filename);
        }
    }
    ~File()
    {
        if (filename)
            cout << "~File(" << filename << ")\n";
        else
            cout << "~File(null)\n";
        if (filename != NULL)
            delete[] filename;
    }
};

class Directory : public File
{
protected:
    int numContents;
    File* contents;
public:
    Directory(FILE* readFromHere, const char* name)
        : File(readFromHere, name)
    {
        numContents = 2;
        contents = new File[numContents];
        contents[0] = File(readFromHere, "a.out");
        //~ contents[1] = File(readFromHere, "otherfile.cpp");
    }
    ~Directory()
    {
        if (filename)
            cout << "~Directory(" << filename << ")\n";
        else
            cout << "~Directory(null)\n";
        if (contents != NULL)
            delete[] contents;
    }
};

int main()
{
    Directory d(NULL, "randname");
    sleep(2);
    return 0;
}
Was it helpful?

Solution

Your class doesn't follow the Rule of Three even though it owns resources. You have a copy constructor and a destructor, but not a copy assignment operator. Which means that this line:

contents[0] = File(readFromHere, "a.out");

invokes the default copy assignment operator, which happily copies pointers. There's your double-deletion problem.

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