0

リンクされたスタック、つまりstructとtypedefを使用して、指定されたポイントで文字列を文字列に挿入する宿題をしようとしています。とにかく、InsertAfterメソッド内のStringModifierクラスのstringLengthにアクセスしようとすると、実行時エラーが発生し、問題が何であるかを理解できません。変数は保護されており、派生クラスはパブリックに継承されているため、変数にアクセスして変更できるはずです。

struct StringRec
{
    char theCh;
    StringRec* nextCh;
};

typedef StringRec* StringPointer;

class String
{
    public:
        String();
        ~String();
        void SetString();
        void OutputString();
        int GetLength() const;
    protected:
        StringPointer head;
        int stringLength;
};

class StringModifier : public String
{
    public:
        StringModifier();
        ~StringModifier();
        void InsertAfter( StringModifier& subString, int insertAt );
};

void StringModifier::InsertAfter( StringModifier& subString, int insertAt )
{
// RUN TIME ERROR HERE
    stringLength += subString.stringLength;
}

メインで

StringModifier test;
StringModifier test2;

cout << "First string" << endl;
test.SetString();
test.OutputString();
cout << endl << test.GetLength();
cout << endl << "Second string" << endl;
test2.SetString();
test2.OutputString();
cout << endl << test2.GetLength();
cout << endl << "Add Second to First" << endl;
test.InsertAfter( test2, 2 );
test.OutputString();
cout << endl << test.GetLength();

//String Class

String::String()
{
    head = NULL;
    stringLength = 0;
}

String::~String()
{
// Add this later
}

void String::SetString()
{
    StringPointer p;
    char tempCh;

    int i = 0;
    cout << "Enter a string: ";
    cin.get( tempCh );
// Gets input and sets it to a stack
    while( tempCh != '\n' )
    {
        i++;
        p = new StringRec;
        p->theCh = tempCh;
        p->nextCh = head;
        head = p;
        cin.get( tempCh );
    }

    stringLength = i;
}

void String::OutputString()
{
    int i = stringLength;
    int chCounter;
    StringPointer temp;
// Outputs the string bottom to top, instead of top to bottom so it makes sense when read
    while( head != NULL && i > 0 )
    {
        temp = head;
        chCounter = 0;
        while( temp != NULL && chCounter < (i-1) )
        {
            temp = temp->nextCh;
            chCounter++;
        }
        cout << temp->theCh;
        i--;
    }
}

int String::GetLength() const
{
    return stringLength;
}

StringModifierクラスには、空のコンストラクタとデストラクタがあります。

4

5 に答える 5

3

ヒント:C ++のランタイムエラーは、パブリック/保護/プライベートアクセスとはまったく関係ありません。コンパイラは、コードをコンパイルするときに、すべてのクラスメンバーのアクセスルールが守られていることをすでに確認しています。

ランタイムエラーは、プログラムにバグがあることを意味します。おそらく、何らかのメモリの破損です。

于 2009-10-10T08:03:43.200 に答える
0

ランタイムエラーが実際にInsertAfter関数で発生しますか?stringLengthを変更すると、実際にはまだ文字を追加していないため、OutputStringでアクセス違反が発生するはずです。whileループに(temp!= NULL)句を追加すると、これはほとんど回避されますが、tempがNULLになるために実際にループを離れるとどうなるかを見てください...

あなたのコメントへの返答:私はまだこのランタイムエラーがどこで起こっているのかについて少し懐疑的です!コードが実際に質問で与えられたとおりであり、ビルドが台無しになっていないと仮定すると、InsertAfterにAVなどを含めることはほぼ不可能です(OK、C ++で言うのは危険なことですが、ねえ-スタックに割り当てられているオブジェクトのメンバーの値を変更しているだけです)。InsertAfterメソッドでエラーが発生しているのは、呼び出さないと消えてしまうからではないことに注意してください。実際、OutputStringのバグは、InsertAfterの呼び出しによってのみ明らかになるため、InsertAfterを呼び出すと消えるはずです。呼び出しが削除されます。確認するには、疑わしいステートメントの前後の両方で、デバッガーを使用するか、InsertAfterにログを追加します。

于 2009-10-10T09:49:23.053 に答える
0

Valgrind (無料) または Purify (おそらく無料ではない) でプログラムを実行して、できるだけ早くメモリ エラーを検出することができます。エラーメッセージもより明確になるはずです。

また、プログラムをデバッガーで実行するだけで、クラッシュしたときにその状態を確認できます。それはあなたが期待するものですか?

于 2009-10-11T09:59:33.353 に答える
0

実行時エラーの場所は確かですか? それどうやって確認したの?非常に疑わしい場所が 1 つあります。

while( temp != NULL && chCounter < (i-1) )
{
        temp = temp->nextCh;
        chCounter++;
}
cout << temp->theCh; // temp can be NULL here?

temp != NULL がループ ヘッダーで常に true であるか、場合によっては、それ自体が実行時エラーである NULL ポインター逆参照があります。

于 2009-10-10T10:00:25.517 に答える
0

みんなの助けに感謝します。そもそもリストに間違ったものを追加していたことが判明しました。それをスタックにする代わりに、私はそれをキューにしました。すべてがうまく機能しています! 皆さんからのアドバイスを参考にして、他の場所で問題を探しました。ありがとう!

void String::SetString()
{
    StringPointer p, last;
    char tempCh;
    last = head;
    int i = 0;
    cout << "Enter a string: ";
    cin.get( tempCh );

    while( tempCh != '\n' )
    {
        i++;
        if( i == 1 )
        {
            p = new StringRec;
            p->theCh = tempCh;
            head = p;
            last = p;
        }
        else
        {
            p = new StringRec;
            p->theCh = tempCh;
            p->nextCh = last;
            last->nextCh = p;
            last = p;
        }
        cin.get( tempCh );
    }

    last->nextCh = NULL;

    stringLength = i;
}
于 2009-10-12T22:45:53.093 に答える