[英]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.