2

我有一个接受字符数组的类。我意识到 std::string 更适合处理字符串,但这是学习指针和分配动态内存的练习。我遇到的问题是重载的加法运算符。我将新内存分配给连接的两个 char 数组的大小,加上一个终止的空字符。当我在 for 循环上放置断点时,我可以看到程序正在遍历左侧操作数指针 (p),然后是右侧操作数指针 (q),但各个字符并未存储到 temp_str。

我对 C++ 相当陌生,所以我确信我缺少一些关于指针和/或动态内存的基本知识。任何帮助/建议将不胜感激。谢谢。

#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;
}
4

2 回答 2

1

在复制操作中,您正在执行temp_str++直到temp_str超出您分配的数组的点,因此返回的CStr(temp_str)点也超出了它。

您可以通过在复制循环中使用单独的指针或temp_str在返回之前减去您存储的字符数来轻松解决此问题。

于 2013-08-13T13:59:42.463 回答
1

您在operator+函数中遇到了一个大问题:您从指向字符串之外的指针创建了一个字符串。

当你增加temp_str指针时,你会失去原来的指针,所以当你做return CStr(temp_str)指针指向超出字符串的终止符时。

与其手动将字符串复制到新内存中,不如简单地使用例如memcpywithtemp_str和可能的目标偏移量:

memcpy(temp_str, p, lhs_length);
memcpy(temp_str + lhs_length, q, rhs_length);
temp_str[lhs_length + rhs_length] = '\0';
于 2013-08-13T14:00:56.313 回答