简体   繁体   中英

C++ pointer to new memory storing gibberish

I have a class that accepts character arrays. I realize that std::string is preferred for working with strings but this is an excercise to learn about pointers and allocating dynamic memory. The problem I am having is with the overloaded addition operator. I allocate new memory to the size of the two char arrays being concatenated, plus a terminating null character. When I put breakpoints on the for loops I can see the program is iterating through the left hand operand pointer(p) and then the right hand operand pointer(q), but the individual chars are not being stored to temp_str.

I am fairly new to C++ so I am sure I am missing something basic about pointers and/or dynamic memory. Any help/advice would be appreciated. Thanks.

#include <iostream>
#include <cstring>
using std::cout;
using std::endl;

class CStr
{
private:
    int m_length;
    char* m_pstr;

public:
    // Constructor
    CStr (const char* s = "Default String")
    {
        cout << "Constructor called\n";
        m_length = strlen(s) + 1;           // Store the length of the string
        m_pstr = new char[m_length];        // Allocate space for the string
        strcpy_s(m_pstr,m_length,s);        // Copy string to memory
    }

    // Copy constructor
    CStr (const CStr& aStr)
    {
        cout << "Copy constructor called\n";
        m_length = aStr.m_length;                   // Get length of the object to be copied
        m_pstr = new char [m_length];               // Allocate space for the string
        strcpy_s(m_pstr, m_length, aStr.m_pstr);    // Copy string to memory
    }           

    // Assignment operator
    CStr& operator=(const CStr& aStr)
    {
        cout << "Assignment operator called\n";

        if(this == &aStr)                               // Check addresses, if equal
        return *this;                               // return the 1st operand

        m_length = aStr.m_length;                           // Get length of the rhs operand

        delete [] m_pstr;                               // Release memory for the lhs operand
        m_pstr = new char[m_length];                        // Allocate space for the string

        strcpy_s(m_pstr, m_length, aStr.m_pstr);        // Copy rhs operand string to the lhs operand

        return *this;                                       // Return a reference to the lhs operand
    }  

    // Addition operator
    CStr operator+(const CStr& aStr) const
    {
        cout << "Addition operator called\n";

        // get the lengths of the strings
        size_t rhs_length = strlen(aStr.m_pstr);                    // length of rhs operand
        size_t lhs_length = strlen(this->m_pstr);                   // length of lhs operand

        char* temp_str = new char[lhs_length + rhs_length + 1];     // Allocate memory to hold concatenated string
                                                                    // plus terminating null character
        char* p = this->m_pstr;
        char* q = aStr.m_pstr;

        for (p; *p!=0; p++)             // Increment lhs string pointer 
            *temp_str++ = *p;           // Store character

        for (q; *q!=0; q++)             // Increment rhs string pointer
            *temp_str++ = *q;           // Store character

        *temp_str++ = '\0';             // Null character at the end

        return CStr(temp_str);
    }

    // Destructor
    ~CStr ()
    {
        cout << Print() << " has been destroyed\n";
        delete [] m_pstr;                               // Free memory assigned to the pointer
    }

    // Print function
    char* Print() const
    {
        return m_pstr;
    }
};

int main()
{
    CStr s1("foo");
    CStr s2("bar");

    CStr s3 = s1 + s2;
}

Inside the copy operation, you're doing temp_str++ until temp_str points beyond the array you allocated, so the returned CStr(temp_str) points beyond it as well.

You can easily solve this by either using a separate pointer inside the copy loops, or subtracting the number of characters you stored from temp_str prior to return.

You have a big problem in the operator+ function: You create a string from a pointer that points beyond the string.

When you increase the temp_str pointer you loose the original pointer, so when you do return CStr(temp_str) the pointer points to beyond the terminator of the string.

Instead of manually copy the strings into the new memory, why not simply use eg memcpy with temp_str with a possible offset for the destination:

memcpy(temp_str, p, lhs_length);
memcpy(temp_str + lhs_length, q, rhs_length);
temp_str[lhs_length + rhs_length] = '\0';

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM