Ошибка времени выполнения C ++ с защищенными членами - PullRequest
0 голосов
/ 10 октября 2009

Я пытаюсь выполнить домашнее задание, в котором мы вставляем строку в строку в указанной точке, используя связанный стек, отсюда struct и typedef. В любом случае, когда я пытаюсь получить доступ к stringLength в классе StringModifier внутри метода InsertAfter, я получаю ошибку времени выполнения и не могу понять, в чем проблема. Я должен иметь возможность доступа и изменения переменной, потому что она защищена, а производный класс унаследован публично.

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 имеет пустые конструкторы и деструкторы.

Ответы [ 5 ]

3 голосов
/ 10 октября 2009

Просто подсказка: ошибки времени выполнения в C ++ совершенно не связаны с публичным / защищенным / приватным доступом. При компиляции вашего кода компилятор уже проверил соблюдение всех правил доступа к членам класса.

Ошибка времени выполнения означает, что в вашей программе есть ошибка, скорее всего, какое-то повреждение памяти.

0 голосов
/ 13 октября 2009

Спасибо всем за помощь. Оказывается, я неправильно добавлял вещи в список. Вместо того, чтобы делать это стеком, я сделал это очередью, и все работает отлично! Я принял совет, который вы дали, ребята, и искал проблему в другом месте. Спасибо!

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;
}
0 голосов
/ 11 октября 2009

Вы можете попробовать запустить программу под Valgrind (бесплатно) или Purify (возможно, не бесплатно), чтобы как можно раньше обнаружить ошибки памяти. Сообщение об ошибке также должно быть гораздо более четким.

Кроме того, просто запустите программу под отладчиком, и, когда она выйдет из строя, проверьте ее состояние. Это то, что вы ожидаете?

0 голосов
/ 10 октября 2009

Вы уверены, что обнаружите ошибку во время выполнения? Как ты это проверил? Я вижу одно место, которое очень подозрительно:

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

Либо temp! = NULL всегда имеет значение true в заголовке цикла, либо в некоторых случаях у вас есть разыменование указателя NULL, которое само по себе является ошибкой времени выполнения.

0 голосов
/ 10 октября 2009

Вы уверены, что ваша ошибка во время выполнения действительно происходит в функции InsertAfter? Мне кажется, что когда вы изменяете stringLength, вы должны получить нарушение прав доступа в OutputString, потому что вы на самом деле еще не добавили символы. Добавление предложения (temp! = NULL) в цикл while почти позволяет избежать этого, но посмотрите, что произойдет, если вы фактически выйдете из цикла из-за того, что temp станет NULL ...

Отвечая на ваши комментарии: боюсь, я все еще немного скептически отношусь к тому, где происходит эта ошибка во время выполнения! Если код действительно такой, как приведенный в вопросе, и при условии, что вы не получили испорченную сборку, наличие AV или чего-то еще в InsertAfter было бы практически невозможным (хорошо, это опасно говорить в C ++, но эй - вы просто меняете значение члена объекта, который расположен в стеке). Обратите внимание, что вы не можете сказать, что ошибка возникает в методе InsertAfter только потому, что она исчезает, если вы ее не вызываете - действительно, ошибка в OutputString обнаруживается только при вызове InsertAfter, поэтому она должна исчезнет, ​​если будет удален вызов InsertAfter. Чтобы проверить, используйте отладчик или добавьте некоторые записи в InsertAfter, как до, так и после подозрительного оператора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...