0

I am new bee for c++ . I got follow error when I override operator+ .

ConsoleApplication1.out: /root/projects/ConsoleApplication1/sdstring.cpp:43: static sdstring::size_t sdstring::strlen(const char*): Assertion `str' failed.

This is my test code!

    sdstring sd1(NULL);
    cout << "sd1:" << sd1 << endl;
    sdstring sd2("sd2");
    cout << "sd2:" << sd2 << endl;
    sdstring sd3;
    cin >> sd3;
    cout << "sd3:" << sd3 << endl;

    sd3 +=sd2 ;
    cout << "sd3:" << sd3 << endl;
    sdstring sd4 =sd3+sd1;
    cout << "sd4:" << sd2 << endl;
    sd1 = sd2 + sd1;
    cout << "sd1:" << sd1 << endl;
    cout << "sd3==sd2:" << (sd3 == sd2)<<endl;

Error happened in This line .

sdstring sd4 =sd3+sd1;

This is my sdstring.cpp file.

#include "sdstring.h"
#include <assert.h>



sdstring::sdstring(const char *str) {
    if (!str) {
        datas = new char[1];
        datas[0] = '\0';
    }
    else {
        datas = new char[strlen(str)+1];
        strcpy(datas, str);
    }
}
sdstring::sdstring(const sdstring& str) {
    datas = new char[strlen(str.datas) + 1];
    strcpy(datas, str.datas);
}
sdstring& sdstring::operator+(const sdstring& str)const {
    sdstring result(NULL);
    size_t total_size = getlen() + str.getlen();
    result.datas = new char[total_size + 1];
    strcpy(result.datas, datas);
    strcat(result.datas, str.datas);
    return result;
}

bool sdstring::operator==(const sdstring& str)const {
    return strcmp(datas, str.datas) == 0;
}
sdstring& sdstring::operator=(const sdstring& str) {
    if (this == &str)
        return *this;
    delete[] datas;
    datas = new char[str.getlen() + 1];
    strcpy(datas, str.datas);
    return *this;
}


sdstring::size_t sdstring::strlen(const char* str) {
    assert(str);
    size_t len = 0;
    while ('\0' !=  *str++)
        len++;
    return len;
}
char* sdstring::strcpy( char* des, const char* src){
    assert(des&& src);
    char* temp = des;
    while ('\0' != (*des++ = *src++));
    return temp;
}
int sdstring::strcmp(const char* fir, const char* sec) {
    assert(fir  && sec);
    while (*fir == *sec)
    {
        if (*fir == '\0') {
            return 0;
        }
        ++fir;
        ++sec;
    }
    return *fir - *sec;
}

char* sdstring::strcat(char* des,const char* src) {
    char* temp = des;
    while ('\0' != *des)
    {
        des++;
    }
    while ('\0' != (*des++ = *src++));
    return temp;
}

sdstring::~sdstring()
{
    if (datas)
    {
        delete[] datas;
        datas = nullptr;
    }
}
char& sdstring::operator[](const unsigned int position)const
{
    return position < getlen() ? datas[position] : datas[position-1];
}
sdstring& sdstring::operator+=(const sdstring& str)
{
    size_t total_size = getlen() + str.getlen();
    if (total_size != getlen()) {
        char* temp = datas;
        datas = new char[total_size + 1];
        strcpy(datas,temp);
        strcat(datas, str.datas);
        delete[] temp;
    }
    return *this;
}
ostream& operator<<(ostream& os, const sdstring& str)
{
    os << str.datas;
    return os;
}
 istream& operator>>(istream& is, sdstring& str)
{
     char* cache = new char[1024];
     is >> cache;
     delete[]str.datas;
     str.datas = new char[sdstring::strlen(cache)];
     sdstring::strcpy(str.datas, cache);
     delete[]cache;
     return is;
}

Who can help me , Thanks for first!

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
Cyrus
  • 8,995
  • 9
  • 31
  • 58

1 Answers1

1

There are several things wrong with your code. However the operator + is wrong in that it is returning a reference to a local variable, which is undefined behavior.

sdstring& sdstring::operator+(const sdstring& str)const 
{
    sdstring result(NULL);
    //..
    return result;  // Undefined behavior.
}

operator + should be returning a brand new object, not a reference to an object.

sdstring sdstring::operator+(const sdstring& str)const // <-- Note the return value is sdstring
{
    sdstring result(NULL);
    //..
    return result;  
}

The other issues with your code:

1) The operator= destroys the memory using delete[] datas; before calling new[] to allocate memory for the new string. If new[] throws an exception, the sdstring object would be corrupted since the data has been destroyed and you can't go back and reset the string with the old data. Use the copy / swap idiom to prevent this from happening.

2) You should store the length of the string in a member variable instead of calling strlen every time you want to know the length of the string. The strlen is slow in that it has to loop to count every single character to determine where the terminating '\0' character is located. Instead of that, just store the length of the string once and keep using that value.

3) Instead of writing your own strlen and strcmp functions, use the library functions strlen and strcmp. Your versions are not optimized, unlike the library versions.

4) operator + can be written in terms of operator +=. operator + should be written very simply as:

sdstring sdstring::operator + (const sdstring& rhs)
{
   return sdstring(*this) += rhs;
}
PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • You are so kind ,Thanks for your patience for my silly question .I will fix those issues . – Cyrus Nov 03 '17 at 05:47