受保护成员的C ++运行时错误

时间:2009-10-10 07:59:01

标签: c++ string class protected

我正在尝试做一个家庭作业,我们使用链接堆栈将字符串插入到指定点的字符串中,因此是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;
}
MAIN中的

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 个答案:

答案 0 :(得分:3)

只是一个提示:C ++中的运行时错误与公共/受保护/私有访问完全无关。编译代码时,编译器已经检查了所有类成员访问规则是否已被遵循。

运行时错误意味着您的程序中存在错误,很可能是内存损坏。

答案 1 :(得分:0)

您确定您的运行时错误实际发生在InsertAfter函数中吗?在我看来,当你修改stringLength时,你应该在OutputString中获得访问冲突,因为你还没有真正添加过字符。将(temp!= NULL)子句添加到while循环几乎可以避免这种情况 - 但是看看如果因温度变为NULL而实际离开循环会发生什么......

回应你的评论:我担心我对这个运行时错误发生的地方仍然持怀疑态度!如果代码确实是在问题中给出的,并且假设你没有搞乱构造,那么在InsertAfter中使用AV或其他东西几乎是不可能的(好吧,这在C ++中说是危险的,但是嘿 - 你只是改变了在堆栈上分配的对象成员的值。请注意,你不能告诉InsertAfter方法中发生错误只是因为如果你不调用它就会消失 - 事实上,OutputString中的错误只是通过调用InsertAfter来暴露,所以它应该<如果删除了InsertAfter调用,则/ em>消失。要检查,请在可疑语句之前和之后使用调试器或向InsertAfter添加一些日志记录。

答案 2 :(得分:0)

您确定运行时错误位置吗?你是怎么检查的?我看到一个非常可疑的地方:

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

temp!= NULL在循环头中始终为true,或者在某些情况下,您确实有NULL指针取消引用,这本身就是运行时错误。

答案 3 :(得分:0)

您可以尝试在Valgrind(免费)或Purify(可能不是免费)下运行您的程序,以尽早检测内存错误。错误信息也应该更清楚。

此外,只需在调试器下运行程序,当它崩溃时,检查其状态。这是你期望的吗?

答案 4 :(得分: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;
}