Skip to Content
Course content

209: Practice Exercise: Building a Custom String Class

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Why can't I just point to an existing C-string?

It's tempting to just store a char* that points to a string literal, but that's a recipe for a segmentation fault. If your class just holds a pointer to memory it doesn't "own," you have no way of knowing if that memory is still valid or if you're allowed to modify it. To build a real string class, you need to manage your own heap memory.

I usually start by allocating a buffer based on the length of the input string plus one for the null terminator. It looks something like this:

class MyString {
    char* data;
    size_t len;

public:
    MyString(const char* str = "") {
        len = std::strlen(str);
        data = new char[len + 1]; // We own this memory now
        std::strcpy(data, str);
    }
    ~MyString() {
        delete[] data; // Clean up or you've got a leak
    }
};

I'm getting a crash when I pass my string to a function. What's happening?

You've probably hit the "shallow copy" trap. By default, C++ does a member-wise copy. If you have a MyString a = "Hello"; and then do MyString b = a;, both a.data and b.data are pointing to the exact same memory address. When the first one goes out of scope, its destructor calls delete[]. Then, when the second one tries to do the same, it's deleting memory that's already gone. Double free. Crash.

This is why you need a copy constructor and a copy assignment operator—the "Rule of Three." You have to explicitly tell C++ to allocate new memory and copy the actual characters over, not just the pointer.

// Copy Constructor
MyString(const MyString& other) {
    len = other.len;
    data = new char[len + 1];
    std::strcpy(data, other.data);
}

// Copy Assignment Operator
MyString& operator=(const MyString& other) {
    if (this == &other) return *this; // Don't delete yourself!

    delete[] data; // Get rid of the old buffer
    len = other.len;
    data = new char[len + 1];
    std::strcpy(data, other.data);
    return *this;
}

How do I make the '+' operator actually work like a real string?

If you want to write str1 + str2, you can't just modify str1 in place; that would be a += operation. The + operator is expected to create a brand new string that is the combination of the two.

The trick here is to allocate a buffer large enough for both strings, join them using strcat (or a loop), and return a new MyString object by value. I personally prefer returning by value here because it's the most intuitive way for the user of your class to chain operations.

MyString operator+(const MyString& other) {
    char* temp = new char[len + other.len + 1];
    std::strcpy(temp, data);
    std::strcat(temp, other.data);

    MyString result(temp); 
    delete[] temp; // Clean up the temporary buffer
    return result;
}



📋 Practical Task

Exercise: Implementing the Memory-Safe String Buffer

Build a custom string class called SecureString that manages its own memory. Your implementation must satisfy the following requirements to ensure it doesn't leak memory or crash during assignments:

  • Manual Memory Management: Use new[] in the constructor and delete[] in the destructor.
  • The Rule of Three: Implement a copy constructor and a copy assignment operator to prevent shallow copy crashes.
  • Concatenation: Overload the + operator to return a new SecureString containing the combined text of two objects.
  • Access: Overload the << operator (friend function) so you can print your SecureString directly to std::cout.

Test your class by creating a string, assigning it to another variable, and concatenating it with a third string to ensure no memory corruption occurs.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.