2

文字配列を受け入れるクラスがあります。std::string は文字列を操作するのに適していると思いますが、これはポインターと動的メモリの割り当てについて学ぶための演習です。私が抱えている問題は、オーバーロードされた加算演算子にあります。連結される 2 つの char 配列のサイズに、終端の null 文字を加えたサイズに新しいメモリを割り当てます。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_strCStr(temp_str)

temp_strこれは、コピー ループ内で別のポインターを使用するか、戻る前に保存した文字数を差し引くことで簡単に解決できます。

于 2013-08-13T13:59:42.463 に答える
1

関数に大きな問題がありoperator+ます。文字列を超えて指すポインターから文字列を作成します。

temp_strポインターを増やすと、元のポインターが失われるため、ポインターを増やすと、ポインターreturn CStr(temp_str)は文字列のターミネーターを超えてポイントします。

文字列を手動で新しいメモリにコピーする代わりに、たとえば、コピー先の可能なオフセットを使用memcpyして単純に使用しないでください:temp_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 に答える