1
Firstly here is my code:

header:

#pragma once
#include <iostream>
using namespace std;
class CString
{
private://Main attribute
    char* str;
private:// Aux attribute
    int len;
public:
//constructor and destructor
    CString(char* x);
    CString() { len = 0; str = NULL; }
    ~CString() 
    {
        if (NULL != str) 
            delete[] str;
        str = NULL;
    }
//some operator
    CString operator+(CString x);
    CString operator+(char* x);
    void operator=(CString x);
//operator() is to extract a part of other CString object
    CString operator()(unsigned pos, unsigned c_len);
//operator[] return position of CString::str[pos]
    char& operator[](unsigned pos);
//Ostream output
    friend ostream& operator<<(ostream& os, CString x);
};
//to do char+CString
CString operator+(char* a, CString x);

header cpp code:

#include "CString.h"

CString::CString(char * x)
{
    len = 0;
    while(x[len])
        len++;
    str = new char[len];
    for (int i = 0;i < len;i++)
        str[i] = x[i];
    if (str[len - 1] != '\0')
    {
        len++;
        char* tmp;
        tmp = new char[len];
        for (int i = 0;i < len - 1;i++)
            tmp[i] = str[i];
        delete[]str;
        str = tmp;
        tmp = NULL;
        str[len - 1] = '\0';
    }
}

CString CString::operator+(CString x)
{
    CString* result;
    result = new CString;
    result->len = this->len + x.len - 1;
    result.str=new char[result.len];
    for (int i = 0; i < this->len - 1;i++)
    {
        result->str[i] = this->str[i];
    }
    for (int i = 0, j = this->len - 1;i < x.len;i++, j++)
    {
        result->str[j] = x.str[i];
    }
    return *result;
}

CString CString::operator+(char * x)
{
    return CString(*this+CString(x));
}

void CString::operator=(CString x)
{
    str = new char[x.len];
    for (int i = 0; i < x.len;i++)
        str[i] = x.str[i];
    len = x.len;
}

CString CString::operator()(unsigned pos, unsigned c_len)
{
    CString* result;
    result = new CString;
    result->len = c_len;
    result.str=new char[c_len];
    for (int i = pos;i < pos + c_len;i++)
        result->str[i - pos] = str[i];
    return *result;
}

char& CString::operator[](unsigned pos)
{
    if (pos < len - 1)
    {
        char* ptr;
        ptr = this->str + pos;
        return *ptr;
    }
    else
    {
        int o_len = len;
        len = pos + 2;
        char* tmp;
        tmp = new char[len];
        for (int i = 0;i < o_len;i++)
        {
            tmp[i] = str[i];
        }
        tmp[len - 1] = '\0';
        delete[]str;
        str = tmp;
        tmp = NULL;
        return *(str + pos);

    }
}

ostream & operator<<(ostream & os, CString x)
{
    os << x.str;
    return os;
}

CString operator+(char * a, CString x)
{
    return CString(CString(a) + x);
}

main:

            CString a("string 1"), b = "Initialize " + a;
            b[15] = '2'; cout << a + " - " + b << endl;
            CString c = a + b;
            cout << "String extracted from string \"" << c
                << "\" from position 3 with length of 6 is: \""
                << c(3, 6) << "\"" << endl;

Problem: When I try to compile this program, there is no error, but still operator+(CString), operator(), and destructor seem to malfunction.

When I debug this program, my program triggered a breakpoint some where at line CString a("String 1"), b = "initilize " + a; I have no idea why. I am do not know if there is any problem for the rest of the program because I always get stuck at that line. SO if somebody can find out any other problem, please tell me, that will save me another day.

Btw, I just wonder at operator+(CString) and operator(), I have create a pointer then I use new and then I return that pointer, so that I have no change to delete that pointer, will it leave me an orphan memory? Since I have read another question about return a class object, I found out that if I use CString result and then return result, result would be destroyed before return. SO is there any better way to do that?

Summary: 1.My program triggered a breakpoint some where in the second line of main(). 2.How to properly return a class object?

P.S: I am really bad at communicating and just have 1 year period of C/C++ learning. So if I have type some thing could give you a cancer, please forgive me.

Sincerely thank you.

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
Silver
  • 29
  • 1
  • 9
  • You forget to add one for the string terminator when you allocate memory. Not that it matters (at least in the constructor) since you seem to overwrite the last character with the terminator. – Some programmer dude Nov 12 '16 at 09:20
  • hmm, actually I do nnot unserstand what "add one for string terminator" mean. Sorry I'm kind of dull – Silver Nov 12 '16 at 09:24
  • You need to read about the [Rule of Three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). The only thing saving this from blowing a hole in its own head is multiple blatant memory leaks. – WhozCraig Nov 12 '16 at 09:26
  • In the constructor you count the number of characters in the string `x`. For example if the input string is `"ab"` then `len` will be `2`, and you allocate space for `2` characters. But the string `"ab"` is actually ***three*** character longs including the terminator. – Some programmer dude Nov 12 '16 at 09:26
  • In your `operator+` method, where are you allocating memory for `result`? Your default constructor sets `len = 0`. – xyz Nov 12 '16 at 09:28
  • I actually aware of that, if 'x' was '"ab"' then when the counter got to 3, it stop. and my 'str' will have no terminator.. Ah now I unserstand what you mean, but the terminator is added after I copy 'x' to 'str'. The reason I doing this is for my operator+ which may copy an unnecessary terminator. – Silver Nov 12 '16 at 09:35
  • thank you @prakharsingh95 I fixed that, but the major problem still not solves, unfortunately. – Silver Nov 12 '16 at 09:40
  • Update the question with your code. – xyz Nov 12 '16 at 09:41
  • @prakharsingh95 updated – Silver Nov 12 '16 at 09:48
  • did you try running it under a debugger? I just did, looks like a double free error. http://ideone.com/NsPZLS – Paul Rooney Nov 12 '16 at 10:12
  • thank you for that answer @PaulRooney I will have a little research right away – Silver Nov 12 '16 at 10:24
  • I also strongly advise you to use the low-level string handling functions from the standard library instead of hand-rolling everything. For example the _while_ loop at the beginning of your ctor is equivalent to _std::strlen()_. – besc Nov 12 '16 at 11:49
  • My other advice is walk before you run. Remove the operator+ overloading and test the class with just construction (all overloads), copy construction and copy assignment. Once you know this to be sound, then try to add operator+. Your operator+ is reliant on your constructors being correct, which they may not be. So that is a good place to start. – Paul Rooney Nov 12 '16 at 12:27
  • Thank you, for all your advice, I will try to do my best. But I wish sb would answer my second question, which is: in my `operator+(CString)` where I return a pointer, will that pointer be destroyed automatically or I must manually destroy it? – Silver Nov 12 '16 at 14:38

0 Answers0