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

发布于 2024-08-07 12:57:59 字数 2481 浏览 7 评论 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;
}

在 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 类有空的构造函数和析构函数。

I am trying to do a homework assignment where we insert a string into a string at a specified point using a linked stack, hence the struct and typedef. Anyway, when I try to access stringLength in the StringModifier class inside the InsertAfter method, I get a run time error and I cannot figure out what the problem is. I should be able to access and modify the variable because it's protected and the derived class is inherited publicly.

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

in 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;
}

The StringModifier class has empty constructors and destructors.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

染墨丶若流云 2024-08-14 12:57:59

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

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

Just a hint: Runtime errors in C++ are completely unrelated to public/protected/private access. The compiler, when compiling your code, has already checked that all the class member access rules are followed.

A runtime error means that you've got a bug in your program, most probably memory corruption of some kind.

一身仙ぐ女味 2024-08-14 12:57:59

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

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

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

Are you sure about run time error location? How did you checked that? I see one place which is very suspicious:

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

Either temp != NULL is always true in loop header or in some cases you do have NULL pointer dereference which is itself a run time error.

我还不会笑 2024-08-14 12:57:59

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

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

You can try running your program under Valgrind (free) or Purify (probably not free) to detect memory errors as early as possible. The error message should also be much more clear.

Also, just run the program under a debugger, and when it crashes, check its state. Is it what you expect?

静水深流 2024-08-14 12:57:59

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

响应您的评论:我'恐怕我仍然对这个运行时错误发生在哪里有点怀疑!如果代码确实如问题中给出的那样,并且假设您没有混乱的构建,那么在 InsertAfter 中拥有 AV 或其他内容几乎是不可能的(好吧,在 C++ 中说这是一件危险的事情,但是嘿 - 您只是更改在堆栈上分配的对象的成员的值)。请注意,您无法判断错误发生在 InsertAfter 方法中,只是因为如果您不调用它,错误就会消失 - 实际上,OutputString 中的错误仅通过调用 InsertAfter 才会暴露,因此它应该如果删除 InsertAfter 调用,/em> 就会消失。要进行检查,请使用调试器,或在可疑语句之前和之后向 InsertAfter 添加一些日志记录。

Are you sure your runtime error actually happens in the InsertAfter function? It looks to me like when you modify the stringLength you should get an access violation in OutputString because you haven't actually added the characters yet. Adding the (temp != NULL) clause to your while loop almost avoids this - but look at what happens if you actually leave the loop because of temp becoming NULL...

Responding to your comments: I'm afraid I'm still a bit skeptical about where this runtime error is happening! If the code really is as given in the question, and assuming you've not got a messed-up build, having an AV or something in InsertAfter would be nigh-on impossible (OK, that's a dangerous thing to say in C++, but hey - you're just changing the value of a member of an object that is allocated on the stack). Note that you can't tell that the error is occurring in the InsertAfter method just because it goes away if you don't call it - indeed the bug in OutputString is only exposed by the call to InsertAfter, so it should disappear if the InsertAfter call is removed. To check, either use a debugger, or add some logging to InsertAfter, both before and after the suspect statement.

身边 2024-08-14 12:57:59

感谢大家的帮助。事实证明,我一开始就在列表中添加了错误的内容。我没有将其设置为堆栈,而是将其设置为队列,一切都运行良好!我听取了你们提供的建议,并在其他地方寻找问题。谢谢你!

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

Thanks for everyone's help. It turns out I was adding things to the list wrong to begin with. Instead of making it a stack I made it a Queue and all is working great! I took advice you guys gave and looked elsewhere for the problem. Thank You!

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文