個人學生
yang1067155909給我來信,說的是
C++第11周項目3 - CEmployee類繼承自CPerson類中的一個細節: 賀老師: 老師,m_szDepartment=new char[strlen(department)+1];爲什麼須要+1呢?在測試裏去掉+1後和這個效果同樣啊,不太明白……求指教…… 學生,楊騰飛 我回答: 要給'\0'佔個座。是用別人的地盤(越界的部分)保存了本身的信息了吧,不定哪次人家要用,運行結果就不同了。這恰是最危險的問題。 他繼續追問: 但是在定義字符數組時,好比a[4]時,能夠輸入5個字符,那麼這個數組的'\0'的位置是否是也佔用了別人的? 我爲這個機靈的同窗的問題感到激動,讀程序,切忌只是讀,要會提問題。能本身提出問題,就必定能學好。老師給出解答,接着再提出新問題,本身解答,或再問老師,這就是交流。爲着學生提出了好問題,做爲老師,我驕傲。個人回答是: 你提的問題不是通常的好,見我新發表的博文談這個問題。 下面就是我對這個問題的解答。不妨針對問題設計一個程序試一試。程序是:
- #include <iostream>
- using namespace std;
- int main()
- {
- char a[4];
- cin>>a;
- cout<<a<<endl;
- return 0;
- }
親愛的讀者,讀這篇文章時,請不要只「讀」,打開你熟悉的編程環境,邊讀邊運行。你會發現什麼? 輸入abcd而後回車,輸出是abcd。cout<<a是將字符數組當字符串輸出的,顯然abcd已經佔滿了本身的地盤a[0]到 a[3],可以「如願」輸出,實際上已經侵佔了不應占的內存a[4]單元。固然,剛好a[4]處給臉,就是'\0'。若是」燙燙燙燙燙燙「沒必要意外。 再運行,輸入abcde。我運行的結果是,在VC++6.0中,輸出abcde,並彈出了咱們熟悉的內存越界錯誤提示。在codeBlocks下,輸出abcde,什麼也沒提示。 請讀者想一想,這是一個多麼兇險的Bug。 下面再給出一個程序:
- #include <iostream>
- using namespace std;
- int main()
- {
- char a[4],b[4];
- cin>>a;
- cin>>b;
- cout<<a<<endl;
- cout<<b<<endl;
- return 0;
- }
運行的任務交給讀者了,觀察輸入3個字符、4個字符、5個字符的情形,也能夠在多個平臺上試試,針對結果想一想爲何。用單步執行的手段跟蹤一下內存中的數據存儲,是個強烈建議的辦法。 下面是爲a和b數組輸入3個字符後(分別是abc和hij),利用單步執行看到的結果:
下面是爲a和b數組輸入5個字符後(分別是abcef和hijkl),利用單步執行看到的結果:
從中看出,VC++6.0中,先定義的a數組的地址大於後定義的數組b的地址,原本爲a中輸入了abcde,侵佔了別人的地盤,隨後爲b輸入hijkl,侵佔的就是a的地盤,b[4]即a[0]爲l,b[5]即a[1],存儲的是'\0'! 下圖是在codeBlocks下,用一樣的輸入調試截出的結果,結果同樣:
接下來,再給一個程序,其實就是將輸入a和b的順序換了一下:
- #include <iostream>
- using namespace std;
- int main()
- {
- char a[4],b[4];
- cin>>b;
- cin>>a;
- cout<<a<<endl;
- cout<<b<<endl;
- return 0;
- }
運行結果會是怎樣?讀者你本身說吧。不要忘了,用調試工具這個法寶解除你的疑惑。
文章轉自http://blog.csdn.net/sxhelijian/article/details/8928528