Overloading + inside a class - Debug Assertion Fail!
I'm trying to get a feel for operator overloading but have run into a problem. The program is just meant to cons two strings. I know there are other ways of doing this already, but I wanted to play. I get the following error:
file: dbgdek.cpp line: 52 _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
I think it is something to do with my use of delete []. Please help I'm really stuck.
#include <iostream>
using namespace std;
class list{
public:
char *value;
int size;
list(int s){size=s; allocmem();};
~list(){delete [] value;};
list operator+(list);
private:
void allocmem(void);
};
void list::allocmem(void){
value=new char[size];
}
list list::operator+(list a)
{
list t(a.size+size);
for (int i=0; i<a.size; i++){
t.value[i]=a.value[i];
}
for (int i=a.size; i<t.size; i++){
t.value[i]=a.value[i-a.size];
}
return t;
}
int main ()
{
list a(2),b(2),c(4);
a.value[0]='a';
b.value[0]='b';
a.value[1]='c';
开发者_Go百科 b.value[1]='d';
c=a+ b;
for (int i=0; i<c.size; i++){
cout<<c.value[i];
}
system("pause");
return 0;
}
Please help!
First warning sign: Your class's destructor does some delete
ing, but the class doesn't define a copy constructor or copy assignment operator.
See the Rule of Three.
You are probably accidentally making temporary copies of the objects and messing them up when the temporary destructor is called.
You need to define the assignment operator (list::operator=(list const&)
) and the copy constructor (list::list(list const&)
) for your class to avoid duplicate deletion of the memory in the destructor. If you don't define those functions the compiler will use the default generated versions of those, which essentially create a bitwise copy of the list object. This is disastrous as after copying an instance of your list both instance will have the same pointer value, causing the duplicate deletion.
You need to do 2 things:
- create a copy constructor that creates its own copy of the data
- pass by reference, not value.
You are passing by value in operator +()
. This will pass a copy of the object (not what you want; you want to pass a reference). But because you didn't create a copy constructor, the copied object gets a default member-by-member copy - now 2 objects have the same pointer. The first one deletes it fine, and the second object now has an invalid pointer.
Instead of working with char*
strings directly, why not use std::string
? Then you don't have to worry about memory management problems (in this case, double delete due to not implementing a copy constructor as others noted). In the most literal translation that would be something like:
class list
{
public:
std::string value;
int size;
list(int s){size=s; allocmem();}
~list(){}
list operator+(list);
private:
void allocmem(void);
};
void list::allocmem(void){
value.resize(size);
}
Note that there are almost certainly better implementations using string
more normally (for example size
can go away). Additionally you probably shouldn't have all your attributes public
.
精彩评论