Double free or corruption error

I'm working on a project for which I'm trying to implement a vector class, but upon execution I keep getting the error message "double free or corruption (fasttop)". I've searched around online and gather that this is probably due to attempting to free the same memory twice, but I can't find my mistake. Below is a slimmed down version of my code that reproduces the error. Any help would be much appreciated.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
struct vec{
	int i;
	double *v;
	vec();
	vec(int n);
	vec(int n, double a);
	~vec();
	vec operator= (vec);
};
// implement constructors
vec::vec(){i=0; v=0;}
vec::vec(int n){
	i=n;
	v = new double[i];
}
vec::vec(int n, double a){
	i=n;
	v = new double[i];
	for(int k=0;k<i;k++) v[k]=a;
}
//implement destructor
vec::~vec(){ if(v!=0) delete[] v;}
//implement = operator
vec vec::operator=(vec par)
{
	if(i!=par.i)
	{
		if(v!=0) delete[] v;
		i=par.i;
		v = i>0 ? new double[i] : 0;
	}
	for(int k=0;k<i;k++) v[k]=par.v[k];
	return *this;
}

int main(){
	vec a(5,2.);
	vec b(4,3.);
	vec c(5,1.);
	vec d;
	a=c;
	return 0;
}


Commenting out the destructor removes the problem but causes memory leaks and crashes (not in this code of course, as it's way to small, but in the full version of my project) The error originates in the last line (a=c), which is why I'm trying to create my own = operator.
Last edited on
The problem lies in your assignment operator method. You are passing the argument by value to this method. Therefore, when you assign by calling a=c, the pointer v in your object c gets copied to the par object defined as a parameter to the assignment operator method. When the method completes, par object gets destroyed and so does the pointer v that was copied to par. This now leaves object c with a dangling pointer. Now when main terminates, c gets destroyed & will attempt to delete the pointer v within c which was deleted already and generates the error.

You may fix this by passing the argument by reference to the assignment operator method. You should also return a reference from the assignment operation to support chained assignments.
hello thijsvp,

the problem is here: vec operator= (vec); and vec vec::operator=(vec par) it copies the data (pointers) on entry and exit of the function without involving the operator= each time since your operator is not a valid copy operator

this is the right one:
vec &operator= (const vec &par); and vec &vec::operator=(const vec &par) note the referenc operator (&)


EDIT: too late
Last edited on
Thanks to both of you. Sadly, in my bigger project this creates a ton of errors of the type "no match for operator=", but I'll see if I can't find a way to fix those after I've read up on passing by reference rather than value. As you might have guessed, I'm rather new to C++.
If you are new to C++, and don't want to be relegated to debugger hell, the more you need to write code in small pieces at a time and test everything you write. Maybe even write the tests before you start to write code. I recommend that you look into:

googletest
valgrind

and read everything about constructors, destructors, assignment operators, and copy constructors very carefully.

You have two choices to go from your bigger project. Break it down into small enough pieces that you can test, or start over and write little pieces at a time and test.

With something as fundamental as not understanding references, there are going to be a lot of bugs and inefficient code in your larger project.
thijsvp wrote:
Thanks to both of you. Sadly, in my bigger project this creates a ton of errors of the type "no match for operator="
do you really use const vec &par? Then there should be no difference passing paramter by value or const reference, hence no errror
It turned out my previous errors were just due to some stupid oversight in changing some other functions. It's currently compiling, but not running (segmentation fault), but I'm sure I'll be able to find the error.

@kfmfe04: Thanks for the advice. I did, of course, test the parts of my code I made previously, but missed a memory leak (which wasn't very noticeable for small snippets of code), and after fixing that things sort of got worse. And yes, I realise that it's going to be a steep learning experience, but my aim is to learn to program as much as to create good code. And I'm definitely learning a lot of useful fundamentals at the moment. :)
If you are on a *nix system, use valgrind (you may be able to use it on Windoze - I dunno):

http://valgrind.org/

It's even easier than purify (no need to recompile/relink). Just type:

valgrind nameOfYourApp

and instantly, it will tell you of suspicious memory leaks, memory overwrites, double frees, uninitialized variables, etc... I use it as part of my build before checking in any code. In other words, let the machine tell you what's wrong rather than trying to debug your code straight (too time consuming!).

Good luck!
Last edited on
Topic archived. No new replies allowed.