[ACCEPTED]-C++ error: double free or corruption (fasttop)-vector
You forgot to define operator=
for your class. This 2 is the rule of Big Three (copy ctor, dtor, assignment 1 must all be defined).
n.m. has already given a fine answer, but 18 I found this question interesting so I decided 17 to try to understand it a little better.
It 16 turns out then when you call erase()
on the first 15 item of an iterator (which we will call 14 item0
), here's what the iterator does: it uses 13 the =
operator of your class to do item0 = item1
. Then 12 it deletes item1
.
If you don't define your own 11 =
operator, I think it will simply copy the 10 memory of your object over from item1
to item0
, so 9 item0
and item1
will temporarily be pointing to the 8 same string. Then when item1
gets deleted, the 7 string gets freed, leaving item0
in an invalid 6 state because it has a pointer to memory 5 that has been freed.
Here is some simple 4 test code that reproduces and illuminates 3 the problem:
#include <cstring>
#include <vector>
#include <stdio.h>
using namespace std;
class Cube
{
public:
char * str;
Cube(const Cube &c) { set(c.str); }
Cube(const char * s) { set(s); }
~Cube() { clear(); } // is "delete []" necessary? not sure
#if 1 // change to 0 to cause a bug
void operator=(const Cube &c)
{
clear(); // necessary to avoid memory leaks
printf("operator=\n");
set(c.str);
}
#endif
private:
void set(const char * s)
{
str = new char[strlen(s) + 1];
printf("allocated %p for %s\n", str, s);
strcpy(str, s);
}
void clear()
{
if (str)
{
printf("freeing %p: %s\n", str, str);
delete str;
}
}
};
int main(int argc, char ** argv)
{
printf("== CREATING VECTOR ==\n");
vector <Cube> vec;
vec.push_back(Cube("octopus"));
vec.push_back(Cube("squid"));
printf("== BEGINNING ITERATION ==\n");
vector<Cube>::iterator it = vec.begin();
printf("First entry is %p %s\n", it->str, it->str);
it = vec.erase(it);
printf("Second entry is %p %s\n", it->str, it->str); // this prints garbage if Cube has no = operator
return 0;
}
This code produces the following 2 output:
== CREATING VECTOR ==
allocated 00350F98 for octopus
allocated 00350FB8 for octopus
freeing 00350F98: octopus
allocated 00350F98 for squid
allocated 00350FD8 for squid
allocated 00350FE8 for octopus
freeing 00350FB8: octopus
freeing 00350F98: squid
== BEGINNING ITERATION ==
First entry is 00350FE8 octopus
freeing 00350FE8: octopus
operator=
allocated 00350F98 for squid
freeing 00350FD8: squid
Second entry is 00350F98 squid
freeing 00350F98: squid
I compiled and ran this in Windows 1 with MinGW. The command I used was g++ -Wl,--enable-auto-import test.cpp && a.exe
.
If it hurts, don't do it:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Cube
{
public:
string str;
Cube(const string& s) : str(s) { }
};
int main()
{
vector <Cube> vec;
for (int i = 0; i < 10; i++)
{
char in [] = "hello !!";
vec.push_back(Cube(in));
}
int i = 0;
for ( vector<Cube>::iterator it = vec.begin(); it < vec.end(); )
{
cout << it->str << endl;
i++;
if (i % 2 == 0)
it = vec.erase(it);
else
it++;
}
for ( vector<Cube>::iterator it = vec.begin(); it < vec.end(); it++)
{
cout << it->str << endl;
}
return 0;
}
Happens to be shorter 1 and correct (not tested).
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.