0

I was bored today and I want to create my own little string class. I really like the 'System.String' class in .Net for it's Split/Replace/Remove etc. functions and I want to attempt to implement them.

My problem however is the destructor. If I have multiple instances of my string class that hold the same string, will all of them try and delete[] the same memory when the destructor is called??

For example:

void DoSomething() {
    MyStringClass text = "Hello!";
    {
        MyStringClass text2 = text;
        // Do something with text2
    } // text2 is destroyed, but so is the char* string in memory
    // text now points to useless memory??
}

Am I understanding this right? Lol.

Thanks,

Alex

EDIT:

Oops, I forgot to include the code:

class string {
    unsigned int length;
    char* text;

public:

    string() : length(0), text(NULL) { }

    string(const char* str) {
        if (!str) throw;
        length = strlen(str);
        text = new char[length];
        memcpy(text, str, length);
    }

    ~string() {
        delete[] text;
    }
};
JohnMcG
  • 8,709
  • 6
  • 42
  • 49
Noah Roth
  • 9,060
  • 5
  • 19
  • 25
  • 7
    It's impossible to say, because you haven't shown us any relevant code. But you should read about the [Rule of Three](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – Oliver Charlesworth Jun 05 '12 at 20:31
  • If you have multiple strings constructed from the same const char *, then of course they don't share the same storage, because you explicitly new the storage and memcpy into it. But if you copy or assign a string, it will get the same storage, and the both will try to delete the same storage, because… well, read the Rule of Three, as suggested above. – abarnert Jun 05 '12 at 20:41
  • 1
    PS, the usual way to follow the Rule of Three is to define all Three. But in this case, you might want to consider something different: a stringholder class that's noncopyable, and has a destructor, and then you can have string classes that use stringholder differently (deep-copying by just having the stringholder as a member, refcounting by just having shared_ptr, etc.) without having to define any of the three. – abarnert Jun 05 '12 at 20:44
  • PPS, if you want Split/Replace/Remove/etc., the idiomatic C++ way is to make them free functions that take a string. Or, even better, write them as generic algorithms that can take any container or range that's sufficiently string-like. Then you don't need to implement a string class from scratch (and then implement your own vector just to copy and paste Replace so you can use it on vectors, etc.). – abarnert Jun 05 '12 at 20:47

1 Answers1

1

You are correct -- both will attempt to delete [] the same memory block.

You did not define a copy constructor for your class, so you will get the default one, which performs a shallow copy of your pointer.

When text2 falls out of scope, the pointer will be delete []d. When text1 falls out of scope, the same pointer will be delete []d again, resulting in undefined behavior.

There are a number of ways to get around this, the simplest being to define your copy constructor and assignment operator.

JohnMcG
  • 8,709
  • 6
  • 42
  • 49