Reputation: 5781
Im writing string class by myself. And I overloaded + operator. Its works fine, but then I tried to eguate cstr = str +pop
, its did nothing. `You could see my error in main() function. Complier doesnt give any mistake.
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
class S {
public:
S();
S(const char *str);
S(const S &s);
~S() { delete []string;}
S &operator =(const S &s);
int lenght() const {return l ;}
char* strS() const {return string;}
friend ostream &operator <<(ostream &, const S &first) {cout<<first.string;}
friend S operator+ (const S& first, const S& second);
private:
char *string;
int l;
};
int main(){
S pop("Q6");
S str("M5");
S cstr = str +pop; // works correct
cout<<str;
str = str + pop;
cout<<str ; // doesnt work, it doesnt write in terminal
return 0;
}
S::S()
{
l = 0;
string = new char[1];
string[0]='\0';
}
S::S(const char *str)
{
l = strlen(str);
string = new char[l+1];
memcpy(string, str, l+1);
}
S::S(const S &s)
{
l = s.l;
string = new char[l+1];
memcpy(string,s.string,l+1);
}
S &S::operator=(const S &s)
{
if (this != &s)
{
delete []string;
string = new char[s.l+1];
memcpy(string,s.string,s.l+1);
return *this;
}
return *this;
}
S operator +(const S& first, const S& second)
{
S temp;
temp.string = strcat(first.strS(),second.strS());
temp.l = first.lenght() + second.lenght();
return temp;
}
I`m looking forward to your help.
Upvotes: 1
Views: 4962
Reputation: 153899
Check the description of strcat
. It appends the second argument to
the first, supposing both are null terminated strings, and returns the
first argument. In your case:
it appends to the string
member of first, although there isn't
enoguh memory for it (undefined behavior), and
it sets the string
pointer in temp
to point to the same memory as
that in first
; the first one to be destructed leaves the other
pointing to deleted memory, and the memory allocated in the default
constructor of temp
is leaked.
Also, you never terminate your strings with '\0'
, so strcat
may do
just about anything.
A better solution would be to implement +=
first, and define +
in
terms of it. +=
would have to grow the memory it has, and append the
text from the second string to it.
And while I'm at it: your operator=
doesn't work either. It will
leave the object in a state where it cannot be destructed if the new
fails (throwing std::bad_alloc
). You must ensure that all operations
that can fail occur before the delete
. (The fact that you need to
test for self assignment is a warning sign. It's very rare for this
test to be necessary in a correctly written assignment operator.) In
this case, the swap idiom would probably be your best bet: copy
construct a new S
in a local variable, then swap their members.
Upvotes: 0
Reputation: 24347
Your operator has bugs!
S temp;
//^^^^ has only one byte buffer!!!
temp.string = strcat(first.strS(),second.strS());
// 1 byte ^^^^^ strcat appends second.strS to first.strS
You should re-allocate memory for temp:
S temp;
temp.l = first.lenght() + second.lenght();
delete [] temp.string; // !!!! -
temp.string = new char[temp.l + 1]; // !!!!
// you should have another c-tor which can allocate memory!!!
// like: S(unsigned length, unsigned char c = '\0')
strcpy(temp.string, first.strS());
strcat(temp.string, second.strS());
Besides this obvious bug - you should also take care of exceptions - std::bad_alloc
for example. Look at copy-and-swap idiom for better approach for this task.
Upvotes: 3
Reputation: 8027
The problem is that your operator+
doesn't allocate any memory for the combined string. Nor does it copy the string to right place (it copies the string to first, not to temp). There's no easy fix with the class design you have.
Upvotes: 1
Reputation: 2108
The problem is with your implementation of operator+
. strcat()
appends the string ponted by the second argument to the string pointed by the first argument. The return value is the first argument. Therefore on return from operator+
the resulting S
and the first S
argument will be pointing to the same buffer. Which will later be deleted twice...
Upvotes: 0
Reputation: 1334
From the manpage for strcat:
The strcat() and strncat() functions append a copy of the null-terminated string s2 to the end of the null-terminated string s1, then add a termi- nating `\0'. The string s1 must have sufficient space to hold the result.
You're using it as if it allocates room for a new char array, then fills it. But, it doesn't do that.
Upvotes: 2