簡體   English   中英

受保護成員的C ++運行時錯誤

[英]C++ run time error with protected members

我正在嘗試做一個作業分配,其中我們使用鏈接堆棧在指定點將字符串插入字符串,因此使用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類具有空的構造函數和析構函數。

只是一個提示:C ++中的運行時錯誤與公共/受保護/私有訪問完全無關。 編譯器在編譯代碼時已檢查是否遵守所有類成員訪問規則。

運行時錯誤意味着您的程序中存在錯誤,很可能是某種形式的內存損壞。

您確定您的運行時錯誤實際上發生在InsertAfter函數中嗎? 在我看來,當您修改stringLength時,您應該在OutputString中遇到訪問沖突,因為您實際上尚未添加字符。 在您的while循環中添加(temp!= NULL)子句幾乎可以避免這種情況-但請查看如果由於temp變為NULL而實際退出循環會發生什么...

回應您的評論:恐怕我仍然對該運行時錯誤發生的位置有些懷疑! 如果代碼確實是問題中給出的,並且假設您沒有搞砸的構建,那么在InsertAfter中擁有AV或其他內容幾乎是不可能的(好吧,這在C ++中是很危險的事情,但是嘿-您只是在更改在堆棧上分配的對象的成員的值)。 請注意,您不能僅僅因為不調用而導致錯誤消失,就無法判斷出InsertAfter方法中發生了錯誤-實際上,OutputString中的錯誤僅通過對InsertAfter的調用而暴露,因此,如果InsertAfter方法出現,則該錯誤消失通話被刪除。 要進行檢查,請在可疑語句之前和之后使用調試器,或在InsertAfter中添加一些日志記錄。

您確定運行時錯誤的位置嗎? 您是如何檢查的? 我看到一個非常可疑的地方:

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

temp!= NULL在循環標頭中始終為true,或者在某些情況下確實存在NULL指針取消引用,這本身就是運行時錯誤。

您可以嘗試在Valgrind(免費)或Purify(可能不是免費)下運行程序,以盡早發現內存錯誤。 錯誤消息也應該更加清晰。

另外,只需在調試器下運行該程序,然后使其崩潰即可檢查其狀態。 是您所期望的嗎?

感謝大家的幫助。 事實證明,我一開始就將事情添加到列表中是錯誤的。 我沒有將其放入堆棧,而是將其放入隊列,並且一切正常! 我接受了你們的建議,並在其他地方尋找了問題所在。 謝謝!

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM